Als auf der Arbeit einmal Langeweile angesagt war, diskutierte ich mit meinem lieben Arbeitskollegen Boris über Software-Patterns (Entwurfsmuster). Da kam uns die Idee, ein paar Patterns in unserer jeweils bevorzugten Programmiersprache umzusetzen.
Als erstes, da relativ einfach: Singleton, also beispielsweise eine Klasse, die sich nur einmal instanzieren lässt und eine Funktion bereitstellt, die diese Instanz zurückgibt (“new” oder “instance”).
Er überraschte mich schon kurz danach mit einer Implementation in Perl, die er ohne Online-Hilfe einfach so mal kurz geschrieben hat. Ich war von den Socken, denn Singleton wird in Perl nicht direkt angeboten. Da hat sich sein großes Talent wieder mal gezeigt. Gleichzeitig war ich froh, dass ich in Ruby schon Schnittstellen für verschiedenste Pattern zur Verfügung habe, denn ich bin nicht wirklich der geborene Programmierer.
Hier die Boris’ Perl-Version, in Form eines Moduls und eines Testskriptes, bitte erwartet keine genaue Erklärungen von mir, was z.B. die Funktion “bless” genau macht usw.:
einzelgaenger.pm:
package einzelgaenger;
use strict;
my $ref = 0;
my $class = '';
sub getInstance {
$class = shift;
unless ($ref) {
$ref = {};
bless($ref,$class);
}
return($ref);
}
sub say {
my $this = shift;
if ($this->{'hit'}) {
print "AUTSCH! Ich sag nichts mehr, du!\n";
}
else {
print "Ich bin ein $class. Mich gibt es nur einmal, egal
wie oft du mich instanzierst, du bekommst immer: $this\n";
}
}
sub hit {
my $this = shift;
$this->{'hit'} = 1;
print "*klaps!*\n";
}
1;
einzelgaenger-test.pl:
use strict; use einzelgaenger; print <<TEXT; Wulli & Peter - Das Singleton-Pattern *************************************** TEXT print "Wir machen uns einen Wulli.\n"; my $wulli = einzelgaenger->getInstance(); print "Wir machen uns einen Peter.\n\n"; my $peter = einzelgaenger->getInstance(); print "Wulli sagt: "; $wulli->say(); print "Peter sagt: "; $peter->say(); print "\nWir schlagen Wulli... "; $wulli->hit(); print "Peter sagt: "; $peter->say(); print "\nWulli und Peter sind ein und der selbe!\n"; print "\n"; exit 0;
Hier der Output:
Wulli & Peter - Das Singleton-Pattern *************************************** Wir machen uns einen Wulli. Wir machen uns einen Peter. Wulli sagt: Ich bin ein einzelgaenger. Mich gibt es nur einmal, egal wie oft du mich instanzierst, du bekommst immer: einzelgaenger=HASH(0x8968c28) Peter sagt: Ich bin ein einzelgaenger. Mich gibt es nur einmal, egal wie oft du mich instanzierst, du bekommst immer: einzelgaenger=HASH(0x8968c28) Wir schlagen Wulli... *klaps!* Peter sagt: AUTSCH! Ich sag nichts mehr, du! Wulli und Peter sind ein und der selbe!
Und hier dasselbe in Ruby. Es zeigt wieder mal, dass Ruby die ideale Sprache ist für schreib- und denkfaule Admins wie ich einer bin:
#!/usr/bin/env ruby
require 'singleton'
class Einzelgaenger
include Singleton
def id_ausgeben
self.object_id
end
end
peter = Einzelgaenger.instance
wullie = Einzelgaenger.instance
print "Peter sagt: \"Hallo, ich bin der Peter, meine ID ist: #{peter.id_ausgeben}!\"\n"
print "Wullie meint dazu: \"Hmmm...seltsam, mein ID ist: #{wullie.id_ausgeben}!?!\"\n"
print "\nPeter und Wullie sind also ein und derselbe! Von Einzelgaenger kann keine weitere Instanz gebildet werden\n"
Hier der Output:
Peter sagt: "Hallo, ich bin der Peter, meine ID ist: -604372568!" Wullie meint dazu: "Hmmm...seltsam, meine ID ist: -604372568!?!" Peter und Wullie sind also ein und derselbe! Von Einzelgaenger kann keine weitere Instanz gebildet werden.
Als nächstes war dann das Beobachter-Muster dran, aber dazu später mehr…

Mal schauen ob jetzt ein Perl-Guru kommt und meinen Code verbessert >_<
Leider ist der Skalar, welcher die Referenz enthaelt, von aussen modifizierbar.
In meinen Augen absolut unschön!
@gd
Ich nehme an du redest vom Perl-Beispiel?
War nur ein proof of concept.
So wie ich dich verstehe stört dich, dass jeder die Singleton-internen-Variablen beliebig verändern kann?
Dies lässt sich lösen -> http://bosseite.ch/wiki/doku.php?id=howtos:programming:perl:private_perl