Objektorientierte Perl-Konstruktor-syntax, die auch benannte Parameter
Ich bin ein wenig verwirrt über das, was Los ist in Perl Konstruktoren. Ich habe diese beiden Beispiele perldoc perlbot.
package Foo;
#In Perl, the constructor is just a subroutine called new.
sub new {
#I don't get what this line does at all, but I always see it. Do I need it?
my $type = shift;
#I'm turning the array of inputs into a hash, called parameters.
my %params = @_;
#I'm making a new hash called $self to store my instance variables?
my $self = {};
#I'm adding two values to the instance variables called "High" and "Low".
#But I'm not sure how $params{'High'} has any meaning, since it was an
#array, and I turned it into a hash.
$self->{'High'} = $params{'High'};
$self->{'Low'} = $params{'Low'};
#Even though I read the page on [bless][2], I still don't get what it does.
bless $self, $type;
}
Und ein weiteres Beispiel ist:
package Bar;
sub new {
my $type = shift;
#I still don't see how I can just turn an array into a hash and expect things
#to work out for me.
my %params = @_;
my $self = [];
#Exactly where did params{'Left'} and params{'Right'} come from?
$self->[0] = $params{'Left'};
$self->[1] = $params{'Right'};
#and again with the bless.
bless $self, $type;
}
Und hier ist das Skript, das verwendet diese Objekte:
package main;
$a = Foo->new( 'High' => 42, 'Low' => 11 );
print "High=$a->{'High'}\n";
print "Low=$a->{'Low'}\n";
$b = Bar->new( 'Left' => 78, 'Right' => 40 );
print "Left=$b->[0]\n";
print "Right=$b->[1]\n";
Habe ich gespritzt die Fragen/Verwirrung, die habe ich mit in den code als Kommentare.
- Das ist basic Perl ein, um eine Liste in einen hash. Es wechselt, wobei die erste als Schlüssel und der zweite als Wert. DWIM (do what I mean) ist ein Ziel, das Perl-will-und in der Regel trifft.
- Da diese Seite ist sehr nützlich, wenn es um das Thema "benannte Parameter" (zusammen mit anderen Dingen) ich habe die phrase in den Titel, damit die Leute es finden können.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Antwort auf die Hauptrichtung Ihrer Frage, da ein hash kann initialisiert werden, wie eine Liste von
key => value
pairs, kannst du solche eine Liste an eine Funktion und weisen Sie dann@_
für ein hash. Dies ist die standard-Art zu tun, benannte Parameter in Perl.Beispielsweise
Dadurch wird
%stuff
im Unterprogrammfoo
mit einem hash mit zwei Schlüsseln,beer
undvodka
, und die entsprechenden Werte.Nun in OO Perl, es gibt einige zusätzliche Falten. Wenn Sie verwenden Sie die Pfeiltasten (
->
) - operator eine Methode aufrufen, was war auf der linken Seite der Pfeil stecken geblieben ist auf den Anfang des@_
array.Also, wenn Sie sagen
Foo->new( 1, 2, 3 )
;Dann in Ihrem Konstruktor
@_
wird wie folgt Aussehen:( 'Foo', 1, 2, 3 )
.So verwenden wir
shift
, die ohne argument arbeitet auf@_
implizit, um das erste Element aus@_
, und weisen Sie es$type
. Danach@_
hat nur unsere Namen/Wert-Paare übrig, und wir weisen es direkt ein hash für die Bequemlichkeit.Dann benutzen wir das
$type
Wert fürbless
. Allebless
tut, ist, nehmen einen Verweis (in deinem ersten Beispiel einer hash-ref) und sagen "dieser Hinweis ist in Verbindung mit einem bestimmten Paket." Alakazzam, Sie haben ein Objekt.Denken Sie daran, dass
$type
enthält den string 'Foo', das ist der name von unserem Paket. Wenn Sie nicht geben Sie eine zweite argumentbless
zu verwenden, wird der name des aktuellen Pakets, das wird auch funktionieren, in diesem Beispiel aber wird nicht Arbeit für vererbte Konstruktoren.my($self,%stuff) = @_;
anstelle der Verschiebung..1. In Perl der Konstruktor ist einfach eine Unterroutine namens neue.
Ja, durch Konvention
new
ist ein Konstruktor. Es kann auch eine Initialisierung durchzuführen oder nicht.new
sollte ein Objekt zurückgeben, auf Erfolg oder wirft eine exception (die
/croak
) wenn ein Fehler aufgetreten ist, der verhindert, dass der Objekterstellung.Können Sie den Namen Ihres Konstruktors, was Sie wollen, haben wie viele Konstruktoren, wie Sie möchten, und sogar bauen segnen Objekte in beliebiger name, Raum, den Sie wünschen (nicht, dass das eine gute Idee ist).
.2. Ich verstehe nicht, was
my $type = shift;
nicht an alle, aber ich sehe es immer. Brauche ich es?shift
mit keine Argumente ein argument aus dem Kopf@_
aus und ordnet Sie$type
. Die->
Betreiber leitet die invocant (linke Seite) als erstes argument an das Unterprogramm. Also diese Zeile wird der name der Klasse aus der Liste der Argumente. Und, ja, Sie müssen es..3. Wie funktioniert ein array von Eingaben werden die
%params
hash?my %params = @_;
Zuweisung in eine hash erfolgt in Listen-Kontext-Paare-Liste, die Elemente gruppiert, die als Schlüssel/Wert-Paaren. So
%foo = 1, 2, 3, 4;
, erstellt einen hash, so dass$foo{1} == 2
und$foo{3} == 4
. Dies erfolgt in der Regel zu erstellen, die benannte Parameter für ein Unterprogramm. Wenn die sub übergeben, eine ungerade Anzahl von Argumenten, eine Warnung generiert wird, wenn Warnungen aktiviert sind..4. Was bedeutet " my $self = {};` tun?
Diese Zeile erstellt eine anonyme hash-Referenz und weist es der lexikalisch scoped variable
$self
. Die hash-Referenz werden die Daten gespeichert, die für das Objekt. In der Regel die Schlüssel in der hash haben eine eins-zu-eins-mapping auf die Attribute des Objekts. Also wenn eine Klasse Foo die Attribute "Größe" und "Farbe", wenn Sie überprüfen Sie den Inhalt der ein Foo-Objekt, Sie sehen etwas wie$foo = { size => 'm', color => 'black' };
..5. Angesichts
$self->{'High'} = $params{'High'};
wo kommt$params{'High'}
kommen?Dieser code stützt sich auf die Argumente zu übergeben
new
. Wennnew
genannt wurde wieFoo->new( High => 46 )
, dann wird der hash erstellt, da pro Frage 3 wird ein Wert für den SchlüsselHigh
(46). In diesem Fall ist es das gleiche wie zu sagen$self->{High} = 46
. Aber wenn die Methode aufgerufen wird, wieFoo->new()
dann kein Wert verfügbar sein wird, und wir haben$self->{High} = undef
..6. Was bedeutet
bless
tun?bless
nimmt eine Referenz und ein Mitarbeiter mit einer bestimmten Paket, so dass Sie können es verwenden, um Methodenaufrufe. Mit einem argument, der Verweis assoicated mit dem aktuellen Paket. Mit zwei Argumenten, das zweite argument gibt das Paket ordnen Sie die Referenz mit. Am besten ist es, immer die beiden argument-form, so dass Ihre Konstruktoren vererbt werden können, die durch eine sub-Klasse und noch einwandfrei funktionieren.Endlich, ich werde schreiben Sie Ihre hash-basierte object-accessor als würde ich schreiben, es mit der klassischen OO-Perl.
Deine Frage nicht OO-Perl. Sie sind verwirrt über die Daten-Strukturen.
Einen hash kann initialisiert werden mit einer Liste oder einem array:
Beim aufrufen einer Methode für ein
bless
ed-Referenz, der Referenz vorangestellt, um die Liste der Argumente erhält die Methode:Ausgabe:
Einige Punkte wurden noch nicht behandelt noch:
Nicht ganz. Beim aufrufen des Konstruktors new ist nur eine Konvention. Sie können es nennen, was Sie wollen. Es ist nichts besonderes über diesen Namen aus perl-Sicht.
Beide deine Beispiele nicht zurückkehren, das Ergebnis segnen ausdrücklich. Ich hoffe, dass Sie wissen, dass Sie damit implizit sowieso.
bless
es und gibt die gesegnet Referenz.Bei der Zuweisung eines Arrays zu einem hash, perl behandelt wechselnde Elemente in dem array als Schlüssel und Werte. Array betrachten, wie
Wenn Sie zuweisen, dass auf %hash, erhalten Sie
Das ist eine andere Art zu sagen, dass in perl-Liste/hash-Bau-syntax
","
und"=>"
bedeuten die gleiche Sache.=>
) automatisch Anführungszeichen LS, wenn der LS besteht nur aus [A-Za-z0-9_].In Perl, alle Argumente an Unterprogramme übergeben werden, über das vordefinierte array
@_
.Den
shift
entfernt und liefert das erste Element aus der@_
array. In Perl OO, das ist die Methode invocant-in der Regel der name einer Klasse für Konstruktoren und ein Objekt für andere Methoden.Hashes reduzieren und kann initialisiert werden, indem Listen. Es ist eine gemeinsame trick, um zu emulieren benannte Argumente an Unterprogramme. z.B.
Ignorieren den Namen der Klasse (die ist verschoben aus) die ungeraden Elemente werden hash-Schlüssel und sogar Elemente werden die entsprechenden Werte.
Den
my $self = {}
erzeugt eine neue hash - Referenz zu halten, die Instanz-Daten. Diebless
Funktion ist, was macht die normale hash-Referenz$self
in ein Objekt. Alle es tut, ist hinzuzufügen, einige Metadaten, die die Referenz als die Zugehörigkeit zu der Klasse.Ja, ich weiß, dass ich bin ein bisschen von einem Nekromanten hier, aber...
Während alle diese Antworten sind so hervorragend, dass ich dachte, ich würde erwähnen Elch. Elch macht Konstruktoren einfach (
package Foo;use Moose;
stellt automatisch ein Konstruktor aufgerufennew
(obwohl der name "new" kann überschrieben werden, wenn Sie möchten)) aber nicht nehmen Sie keine Konfigurierbarkeit, wenn Sie es brauchen.Schaute ich einmal durch die Dokumentation für den Elch (das ist ziemlich gut insgesamt, und es gibt viel mehr Tutorials, snippets, um, wenn Sie von google entsprechend), habe ich nie bereut.