Прототипы не плохи, если используется правильно. Трудность состоит в том, что прототипы Perl не работают способ, к которому люди часто ожидают их. Люди со знаниями в других языках программирования склонны ожидать, что прототипы обеспечат механизм для проверки, что вызовы функции корректны: то есть, то, что у них есть правильное число и тип аргументов. Прототипы Perl не являются подходящими для этой задачи. Это неправильное употребление , это плохо. Прототипы Perl имеют исключительную и совсем другую цель:
Прототипы позволяют Вам определять функции, которые ведут себя как встроенные функции.
, Например, Вы могли определить функцию как это:
sub mypush(\@@) { ... }
и вызов это как [1 114]
mypush @array, 1, 2, 3;
, не будучи должен записать \
для взятия ссылки на массив.
, Короче говоря прототипы позволяют Вам создать свой собственный синтаксический сахар. Например, платформа Американского лося использует их для эмуляции более типичного синтаксиса OO.
Это очень полезно, но прототипы очень ограничены:
См. Прототипы в perlsub для всех окровавленных деталей.
Проблема состоит в том, что прототипы функции 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.
Я соглашаюсь с вышеупомянутыми двумя плакатами. В целом использования $
нужно избежать. Прототипы только полезны при использовании аргументов блока (&
), шарики (*
), или ссылочные прототипы (\@
, \$
, \%
, \*
)