Возьмите более простой пример
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
В приведенном выше примере константа Foo
преобразуется в «Бар», так что это "Bar"->new
не вызывает "Foo"->new
. Как вы мешаете разрешению подпрограммы? Вы можете процитировать это.
"Foo"->new();
Что касается влияния на производительность, все не становится хуже, если использовать строку, а не голое слово. Я подтвердил, что сгенерированный optree O=Deparse
такой же. Так что, как правило, кажется, что лучше указывать имена классов, если вы цените правильность.
Это упоминается в программировании на Perl (к сожалению, в контексте косвенного вызова метода )
... так что мы скажем вам, что вы почти всегда можете обойтись без имени класса при условии, что две вещи верны. Во-первых, нет подпрограммы с тем же именем, что и у класса. (Если вы следуете соглашению, что имена подпрограмм, такие как new
стартовые строчные буквы, и имена классов, такие как ElvenRing
стартовые прописные , это никогда не будет проблемой). Во-вторых, класс был загружен одним из
use ElvenRing;
require ElvenRing;
Любое из этих объявлений гарантирует, что Perl знает, ElvenRing
что это имя модуля, что заставляет любое голое имя, как new
перед именем класса ElvenRing
, интерпретироваться как вызов метода, даже если вам случится объявить собственную new
подпрограмму в текущем пакете.
И это имеет смысл: путаница здесь может произойти, только если ваши подпрограммы (обычно строчные) имеют то же имя, что и класс (обычно прописные). Это может произойти только в том случае, если вы нарушите вышеуказанное соглашение об именах.
tldr; Вероятно, это хорошая идея - указывать свои имена классов, если вы их знаете и цените правильность, а не беспорядок.
Примечание: в качестве альтернативы вы можете остановить преобразование голого слова в функцию, добавив к его концу символ a ::
, например, как описано выше Foo::->new
.
Спасибо Ginnz на Reddit за указание на это мне , и Тоби Инкстер за комментарий (хотя это не имело смысла для меня при первом прочтении).
Foo::->new
, как я узнал от икегами.Foo::
имеет преимущество в том, что он предупреждает, еслиFoo
пакет не существуетFoo->
вы можете ожидать, что в вашем пакете нет такой подпрограммы. Но если вы используете Try :: Tiny и ряд других модулей cpan / других внешних источников, кто скажет, использует ли один из них пакет Try, и если да, есть ли в нем сабвуфер Tiny?Явное цитирование имени класса вместо использования голого слова (которое рассматривается как строка) является одним из трех способов избежать синтаксической неоднозначности. Методы Вызывающую класса раздел документации perlobj объясняет.
Посмотрите этот странный случай в действии с демонстрацией ниже.
Его вывод
В остальной части вышеупомянутого раздела документации показано, как защитить себя от неожиданного поведения или непреднамеренных ошибок.
Применительно к вашему вопросу все звонки ниже эквивалентны.
Добавление
::
до конца имеет то преимущество, что выдает полезное предупреждение. Скажи, что ты случайно набралЧто производит
источник