Nehmen Sie ein einfacheres Beispiel
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
Im obigen Beispiel wird die Konstante Foo
in "Bar" aufgelöst, sodass dies "Bar"->new
nicht aufgerufen wird "Foo"->new
. Wie verhindern Sie die Auflösung des Unterprogramms? Sie können es zitieren.
"Foo"->new();
Was die Auswirkungen auf die Leistung betrifft, werden die Dinge nicht durch die Verwendung einer Zeichenfolge anstelle eines Barworts verschlimmert. Ich habe bestätigt, dass das von erzeugte Optree O=Deparse
dasselbe ist. In der Regel ist es daher besser, die Klassennamen zu zitieren, wenn Sie Wert auf Korrektheit legen.
Dies wird in Programming Perl erwähnt (leider im Zusammenhang mit dem indirekten Methodenaufruf ).
... also werden wir Ihnen sagen, dass Sie fast immer mit einem bloßen Klassennamen davonkommen können, vorausgesetzt, zwei Dinge sind wahr. Erstens gibt es keine Unterroutine mit demselben Namen wie die Klasse. (Wenn Sie der Konvention folgen, dass Unterprogrammnamen wie new
Start Kleinbuchstaben und Klassennamen wie ElvenRing
Start Großbuchstaben , ist dies nie ein Problem). Zweitens wurde die Klasse mit einem von geladen
use ElvenRing;
require ElvenRing;
Jede dieser Deklarationen stellt sicher, dass Perl weiß, dass ElvenRing
es sich um einen Modulnamen handelt, der erzwingt, dass jeder bloße Name wie new
vor dem Klassennamen ElvenRing
als Methodenaufruf interpretiert wird, selbst wenn Sie new
im aktuellen Paket zufällig eine eigene Unterroutine deklariert haben .
Und das macht Sinn: Die Verwirrung hier kann nur auftreten, wenn Ihre Unterprogramme (normalerweise Kleinbuchstaben) denselben Namen wie eine Klasse haben (normalerweise Großbuchstaben). Dies kann nur passieren, wenn Sie gegen die oben genannte Namenskonvention verstoßen.
tldr; Es ist wahrscheinlich eine gute Idee, Ihre Klassennamen zu zitieren, wenn Sie sie kennen und Wert auf Korrektheit legen.
Randnotiz: Alternativ können Sie die Auflösung eines Barworts zu einer Funktion stoppen, indem Sie ein ::
am Ende befestigen , z. B. oben Foo::->new
.
Vielen Dank an Ginnz auf reddit, der mich darauf hingewiesen hat , und an Toby Inkster für den Kommentar (obwohl es für mich beim ersten Lesen keinen Sinn ergab).
Foo::->new
wie ich von Ikegami gelernt habe.