Weź prostszy przykład
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
W powyższym przykładzie stała jest Foo
tłumaczona na „Bar”, więc "Bar"->new
nie wywołuje to "Foo"->new
. Jak zatrzymać rozwiązywanie podprogramu? Możesz to zacytować.
"Foo"->new();
Jeśli chodzi o wpływ na wydajność, sytuacja nie ulegnie pogorszeniu, jeśli użyje się ciągu zamiast słowa. Potwierdziłem, że generowany optree O=Deparse
jest taki sam. Zasadniczo wydaje się, że lepiej jest cytować Nazwy klas, jeśli ceni się poprawność.
Jest to wspomniane w Programowaniu w Perlu (niestety w kontekście pośredniego wywołania metody )
... więc powiemy ci, że prawie zawsze możesz uciec od nagiej nazwy klasy, pod warunkiem, że dwie rzeczy są prawdziwe. Po pierwsze, nie ma podprogramu o takiej samej nazwie jak klasa. (Jeśli postępujesz zgodnie z konwencją, że nazwy podprogramów, takie jak new
rozpoczynaj małe litery, i nazwy klas, takie jak ElvenRing
rozpoczynaj wielkie litery , nigdy nie stanowi to problemu). Po drugie, klasa została załadowana jednym z
use ElvenRing;
require ElvenRing;
Każda z tych deklaracji zapewnia, że Perl wie, że ElvenRing
jest nazwą modułu, co zmusza każdą nagą nazwę, taką jak new
przed nazwą klasy, ElvenRing
do interpretacji jako wywołanie metody, nawet jeśli zdarzy się, że zadeklarujesz własny new
podprogram w bieżącym pakiecie.
I to ma sens: zamieszanie może się zdarzyć tylko wtedy, gdy twoje podprogramy (zwykle małe litery) mają takie same nazwy jak klasa (zwykle wielkie litery). Może się to zdarzyć tylko w przypadku naruszenia powyższej konwencji nazewnictwa.
tldr; prawdopodobnie dobrze jest zacytować swoje nazwy klas, jeśli je znasz i cenisz poprawność nad bałaganem.
Uwaga dodatkowa: alternatywnie możesz przerwać rozwiązywanie słowa-słowa w funkcji poprzez umieszczenie a ::
na jego końcu, na przykład powyżej Foo::->new
.
Dziękuję Ginnzowi na reddit za zwrócenie mi na to uwagi i Toby'emu Inksterowi za komentarz (chociaż nie miało to dla mnie sensu przy pierwszym czytaniu).
Foo::->new
, jak dowiedziałem się od ikegami.Foo::
ma tę zaletę, że ostrzega, jeśliFoo
nie jest istniejącym pakietemFoo->
można oczekiwać, że wiesz, że w twoim pakiecie nie ma takiego podprogramu. Ale jeśli używasz Try :: Tiny i wielu innych modułów cpan / innych zewnętrznych źródeł, kto powie, czy jeden z nich używa pakietu Try, a jeśli tak, to czy jest w nim napis Tiny?Jawne cytowanie nazwy klasy zamiast używania samego słowa (które jest traktowane jako ciąg znaków) jest jednym z trzech sposobów uniknięcia dwuznaczności składniowej. Powołując klasę część dokumentacji perlobj wyjaśnia.
Zobacz ten dziwny przypadek w akcji z pokazem poniżej.
Jego wydajność to
Pozostała część wyżej wymienionej sekcji dokumentacji pokazuje, jak zabezpieczyć się przed zaskakującym zachowaniem lub przypadkowymi błędami.
Stosując się do Twojego pytania, wszystkie poniższe połączenia są równoważne.
Dołączenie
::
do końca ma tę zaletę, że daje pomocne ostrzeżenie. Powiedz, że przypadkowo wpisałeśTo produkuje
źródło