новый SomeModule :: SomeName против SomeModule :: SomeName-> new (), в чем разница? - PullRequest
1 голос
/ 22 января 2020

Я очень новичок в perl, поэтому вам придется извинить мое невежество.

Я работаю над устаревшим проектом. У меня нет выделенной IDE, я использую PHPStorm с выделенным плагином Perl. При наведении курсора на ключевое слово new появляется предупреждение Using of fancy calls is not recommended, use TCO::AEMAP->new().

Код, о котором идет речь,

my $aemapper = new TCO::AEMAP();

По сути, он предлагает сделать

my $aemapper = TCO::AEMAP->new();

Есть ли смысл в этом утверждении или это просто соглашение? Я не могу найти много на Google, так как я не совсем уверен, что искать.

1 Ответ

5 голосов
/ 22 января 2020

Версия new Foo называется синтаксис косвенного объекта . Это старомодный способ вызова конструктора в пакете, и он не рекомендуется в современном Perl. Вот частичная цитата соответствующего раздела в perldo c.

Мы рекомендуем вам избегать этого синтаксиса по нескольким причинам.

Во-первых, это может быть смущающим, чтобы прочитать. В приведенном выше примере неясно, является ли метод сохранения, предоставленный классом File, или просто подпрограммой, которая ожидает объект файла в качестве первого аргумента.

При использовании с методами класса проблема еще хуже. Поскольку Perl позволяет именам подпрограмм быть записанными как голые слова, Perl должен угадать, является ли голое слово после метода именем класса или подпрограммы. Другими словами, Perl может разрешить синтаксис как File-> new ($ path, $ data) или new (File ($ path, $ data)).

Для анализа этого кода, Perl использует heuristi c в зависимости от того, какие имена пакетов он видел, какие подпрограммы существуют в текущем пакете, какие голые слова он видел ранее и другие входные данные. Излишне говорить, что эвристика может привести к очень удивительным результатам!

В более старой документации (и некоторых модулях CPAN) этот синтаксис поддерживается, особенно для конструкторов, так что вы все равно можете найти его в дикой природе. Тем не менее, мы рекомендуем вам не использовать его в новом коде.

Альтернативой является вызов new в качестве метода класса для пакета со стрелкой, как в Foo->new. Стрелка -> выполняет три действия:

  1. Она ищет то, что находится слева. В этом случае голое слово Foo выглядит как имя пакета. Поэтому Perl увидит, знает ли он пакет (или пространство имен ) с таким именем.
  2. Он вызывает метод с правой стороны стрелки в этом пакете, который он только что нашел .
  3. В правом аргументе передается вещь, которая в нашем случае Foo, имя пакета, в качестве первого аргумента. Вот почему в объявлении метода вы увидите my ($class, @args) = @_ или аналогичный.

Для всех других объектно-ориентированных вызовов обычно используется синтаксис стрелки. Но есть много старого кода, который использует косвенный синтаксис объекта для new, и особенно старые модули на CPAN все еще используют его в своей документации.

Оба работают, но синтаксис косвенного объекта не рекомендуется. Используйте Foo->new для нового кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...