Philipp Hasenfratz: Class::Accessor

Beitrag lesen

Halihallo Struppi

Eingentlich soll hier ein Fehler erzeugt werden, da in $t2 das feld b nihct existieren soll.

Naja, naja... :-)

Kurz zum Modul:

Variablen von Instanzen (Objekte) lassen sich nicht wie in anderen
Programmiersprachen über $a->c, a.c oder a->c ansprechen, deswegen
gibt es ja überhaupt dieses Modul. Das einzige was dieser Notation
am nächsten kommt ist ein Methodenaufruf: $a->c oder $a->c().

Das Class::Accessor Modul arbeitet nun wie folgt:
Eine Methode ist stets Modulbezogen. Modulbezogene Eigenschaften wie
Modulvariablen (use vars qw() oder our) oder Methoden werden in der
sogenannten Modulsymboltabelle referenziert. Was Class::Accessor nun
macht, ist für jede mk_accessor übergebenen Variablennamen eine
entsprechende Methode anzulegen (und dies eben auf das Modul oder
das *package* bezogen, nicht auf Instanz-/Objektebene).

Das sieht dann etwa wie folgt aus:

my $method = sub { return $_[0]->{variablenname} }
*{$class."::$field"} = $method
   unless defined &{$class."::$field"};

Nun wird über $class->$method $self->{variablenname} zurückgegeben.

Soweit ich jetzt dahinter steige ist das Problem, diese Zeile:
    Foo->mk_accessors($new, @$fields);
Hier muss statt 'Foo' eigentlich $new stehen, was aber nicht geht, da $new natürlich nicht diese funktion 'mk_accessors()' kennt.

Das Problem sitzt noch tiefer ;)
Wenn du dein Vorhaben weiter verfolgen möchtest, gibt es nur folgende
Möglichkeit:

Du speicherst alle *Instanzen/Objekt-Variablen*, die die Instanz
(z.B. $t2) kennt in einem Array/Hash und definierst eigene set/get
Methoden (s. Doku), die testen, ob auf das Feld zugegriffen werden
darf. Wenn nicht, ein croak() oder die() ggf. ein warn() wie immer du
wünschst.
Natürlich könntest du dies auch über AUTOLOAD erreichen, aber das
ändert nichts am Sachverhalt (ist eben auch eine Methode und somit
in der Symboltabelle definiert, welche eben auf Packetebene
arbeitet). Oder du müsstest leider einfach alle benötigten Variablen
als Methoden exportieren, ob sie nun existieren oder nicht...

Oder aber, du musst für jeden Objekttyp eine eigene Klasse schreiben,
was ja normalerweise auch die richtige und bei vielen
Programmiersprachen die einzige Vorgehensweise ist.

Viele Grüsse

Philipp