Почему Perl 5 прототипы функции плохо?

116
задан Community 23 May 2017 в 11:54
поделиться

3 ответа

Прототипы не плохи, если используется правильно. Трудность состоит в том, что прототипы Perl не работают способ, к которому люди часто ожидают их. Люди со знаниями в других языках программирования склонны ожидать, что прототипы обеспечат механизм для проверки, что вызовы функции корректны: то есть, то, что у них есть правильное число и тип аргументов. Прототипы Perl не являются подходящими для этой задачи. Это неправильное употребление , это плохо. Прототипы Perl имеют исключительную и совсем другую цель:

Прототипы позволяют Вам определять функции, которые ведут себя как встроенные функции.

  • Круглые скобки являются дополнительными.
  • Контекст наложен на аргументы.

, Например, Вы могли определить функцию как это:

sub mypush(\@@) { ... }

и вызов это как [1 114]

mypush @array, 1, 2, 3;

, не будучи должен записать \ для взятия ссылки на массив.

, Короче говоря прототипы позволяют Вам создать свой собственный синтаксический сахар. Например, платформа Американского лося использует их для эмуляции более типичного синтаксиса OO.

Это очень полезно, но прототипы очень ограничены:

  • Они должны быть видимы во время компиляции.
  • Они могут быть обойдены.
  • контекст Распространения к аргументам может вызвать неожиданное поведение.
  • Они могут мешать вызывать функции с помощью чего-либо кроме строго предписанной формы.

См. Прототипы в perlsub для всех окровавленных деталей.

121
ответ дан ikegami 24 November 2019 в 02:16
поделиться

Проблема состоит в том, что прототипы функции Perl не делают, какие люди думают, что они делают. Их цель состоит в том, чтобы позволить Вам писать функции, которые будут проанализированы как встроенные функции Perl.

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

117-секундный, прототипы строго не осуществляются. При вызове подпрограммы с &function(...) прототип проигнорирован. Таким образом, они действительно не обеспечивают безопасности типов.

В-третьих, они - жуткий action-at-a-distance. (Особенно $ прототип, который заставляет соответствующий параметр быть оцененным в скалярном контексте вместо контекста списка по умолчанию.)

, В частности, из-за них сложно передавать параметры от массивов. Например:

my @array = qw(a b c);

foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);

sub foo ($;$) { print "@_\n" }

foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);

печать:

a b c
a b
a b c
3
b
a b c

наряду с 3 предупреждениями [приблизительно 114] (если предупреждения включены). Проблема состоит в том, что массив (или часть массива) оцененный в скалярном контексте возвращает длину массива.

, Если необходимо записать функцию, которая действует как встроенное, используйте прототип. Иначе не используйте прототипы.

Примечание: Perl 6 полностью обновит и очень полезные прототипы. Этот ответ применяется только к Perl 5.

69
ответ дан Flimm 24 November 2019 в 02:16
поделиться

Я соглашаюсь с вышеупомянутыми двумя плакатами. В целом использования $ нужно избежать. Прототипы только полезны при использовании аргументов блока (&), шарики (*), или ссылочные прототипы (\@, \$, \%, \*)

30
ответ дан Leon Timmermans 24 November 2019 в 02:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: