Farid Hajji: Perl - Einführung, Anwendungen, Referenz
2., aktualisierte und erweiterte Auflage
Addison-Wesley Longman, ISBN 3-8273-1535-2
IS-A-BeziehungHAS-A-BeziehungASSOCIATION-BeziehungUSES-Beziehungbless() markierte Referenzen@ISA
Class::StructUNIVERSALuntie()
# Verwendung von Objekten:
use SomeClass;
$obj = SomeClass->new($additional, @parameters);
$obj->setName($newname);
print $obj->getPhone();
#### Deklaration einer Klasse:
package SomeClass;
# Klassenvariablen und Funktionen
sub ClassFunction1 { ... }
$counter = 0; # Globale Variable
my $priv = 12343; # Von ausserhalb unsichtbar
# Der kanonische Konstruktor
sub new {
my $classname = shift;
my $self = {}; # Anonymer Namenshash
bless($self, $classname);
$self->_init(@_); # Initialisierungsroutine
return $self;
}
sub _init {
my $self = shift;
$self->{'NAME'} = shift;
$self->{'PHONE'} = shift;
# usw...
}
# Eine beliebige Methode (Akzessorfunktion):
sub name {
my $self = shift;
$self->{'name'} = shift if (@_);
return $self->{'name'};
}
# Vererbung von Methoden aus Basisklassen mit @ISA
@ISA = qw(Baseclass);
# Vererbung von Datenelementen: Aufruf des Basiskonstruktors
sub new {
my $classname = shift;
$self = $classname->SUPER::new->( shift );
$self->{'onemoreelement'} = shift;
return $self; # Nicht nochmal bless() aufrufen!
}
##### Variablenbindung
# Benutzung:
tie %h, 'SomeClass', $additional, @parameters;
$h{$key} = "newvalue"; # Triggert SomeClass::STORE()
print $h{$key}; # Triggert SomeClass::FETCH()
untie %h;
# Implementation von tie()-kompatiblen Klassen
package SomeClass;
use Tie::StdHash;
use vars qw(@ISA);
@ISA = qw(Tie::StdHash); # Oder eine andere Basisklasse
sub FETCH {
my $self = shift;
my $key = shift;
return uc($self->{$key}); # zum Beispiel
}
sub STORE {
my ($self, $key, $newvalue) = @_;
$self->{uc($key)} = $newvalue; # beispielsweise
}
1;
ABadlyHackedUpClass.pm |
Datenelemente als Klassenarrays |
test-that-bad-class.pl |
Testet unseren üblen Hack aus |
AKludgedClass.pm |
Objektattribute als Klassenhashes |
test-that-kludged-class.pl |
Testet unsere verbesserte Klasse |
ANearlyPerfectClass.pm |
Objektattribute in anonymen Arrays |
test-np-object.pl |
Testet die fast perfekte Klasse |
ClassWithAnonHash.pm |
Objektattribute in einem anonymen Hash |
test-hash-object.pl |
Testet die perfekte namenshashbasierte Klasse |
inheritance.pl |
Verwendung von @ISA, Vererbung und AUTOLOAD() |
inheriting-attributes.pl |
Vererbung von Datenelementen |
class-struct.pl |
C-Strukturen als Klassen mit Class::Struct |
varbind-scalar-greetings.pl |
Tageszeitabhängiger Gruß mit tie() |
TimeGreeting.pm |
TIESCALAR-Klasse zum zeitabhängigen Gruß |
varbind-scalar-greetings2.pl |
Tageszeitabhängiger Gruß speichert Namen |
TimeGreeting2.pm |
Wie TimeGreeting.pm; speichert Namen |
varbind-array-bound.pl |
Array mit Überprüfung der Arraygrenzen |
ArrayBound.pm |
Überprüft Indexgrenzen zur Laufzeit |
fetch-url.pl |
Besorgt eine URL über das Netz mit Tie::URL |
Tie/URL.pm |
TIEHASH-Klasse zum Holen von URLs |
Class->new() und Class::new():Class) übergeben. Dies ist im Falle des direkten Aufrufs mit dem doppelten Doppelpunkt nicht der Fall! (1999/12/03, nach einem Hinweis von Joachim Backes)_init() innerhalb des Konstruktors im Beispiel auf der Seite 680, Mitte:
sub new {
# .......
bless $ptr, $class;
$ptr->_init(@others);
# .......
}
sub _init {
my $self = shift;
my @others = @_;
# ........
}
new die Methode _init() mit Hilfe der Pfeilnotation aufgerufen. Das war nur möglich, weil $ptr bereits zuvor mittels bless() zu einem Objekt dieser Klasse gemacht wurde._init() ist folglich eine gewöhnliche Methode der Klasse. Daher ist ihr erstes Argument ja auch $self.$obj dieser Klasse später neu zu initialisieren, z.B. mit $obj->_init(). Der führende Unterstrich in _init() ist jedoch eine (weitverbreitete) Konvention, die besagt, daß diese Methode nur von weiteren Methoden und Funktionen der Klasse, nicht jedoch vom Benutzer derselben aufgerufen werden sollte. Es handelt sich also um eine Art private Klassenfunktion bzw. private Methode, die nur aus Implementationsgründen vorhanden ist, und die nicht zur öffentlichen Schnittstelle der Klasse bzw. des Objekts gehört. (1999/12/03, nach einem Hinweis von Joachim Backes)
$cn->SUPER::new() bzw. $cn->SUPER->new():$cn, die ja schließlig kein Objekt, sondern ein String enthält, zulässig ist. Der Einwand ist berechtigt, kann aber wie folgt beantwortet werden: Durch das weiter oben erwähnte syntactic sugar kann der Konstruktor einer Klasse mit der Syntax Classname->new() aufgerufen werden. Enthält nun $cn den String Classname, kann dann, wieder aufgrund des syntactic sugars ebenfalls der Konstruktor mit $cn->new() aufgerufen werden.SUPER::new() auch SUPER->new() aufgerufen werden kann. Das ist aber nicht der Fall, denn wenn im folgenden Testprogramm SUPER.pl die Zeile
my $self = $cn->SUPER::new($data);
my $self = $cn->SUPER->new($data); # FALSCH!
farid@sun-1:~> ./SUPER.pl Type: Derived1 Data1:data1 Data2:data2
farid@sun-1:~> ./SUPER1.pl
Can't locate object method "SUPER" via package "Derived1"
at ./SUPER1.pl line 23.
SUPER keine echte Klasse ist, sondern eine Pseudoklasse. Die Notation SUPER::new() bezeichnet die (statische) Klassenfunktion new() der Basisklasse, also hier Base::new(). Dagegen würde SUPER->new() davon ausgehen, daß zunächst SUPER eine Methode von Derived wäre (was sie ja natürlich nicht ist), und dann versuchen, diese Methode mit der Pfeilnotation aufzurufen. Wie gesagt, der echte Grund für dieses seltsame Verhalten ist noch obskurer als das! (1999/12/03, nach einem Hinweis von Joachim Backes)
In Vorbereitung
In Vorbereitung
${$ self } durch ${ $self } in:
my $old = ${ $self };
sub display_all {
foreach my $widget (@widgets_in_window) {
$widget->display_window() if ref($widget) eq 'Window';
# ...
}
}
sub display_all {
foreach my $widget (@widgets_in_window) {
$widget->display(); # Je nach Typ anderes display()
}
}
[Alte Quelle]
| Last modified: $Date: 2006/05/18 12:55:45 $ FH. Search :: Sitemap :: Disclaimer :: Copyright :: Privacy |
|