Я использовал Perl в течение некоторого времени, но сегодня я столкнулся с этим кодом:
sub function1($$)
{
//snip
}
Что это означает в Perl?
Это функция с прототипом , которая принимает два скалярных аргумента.
Существуют веские аргументы в пользу того, чтобы вообще не использовать прототипы Perl - как указано в комментариях ниже. Самый сильный аргумент, вероятно, такой:
Там обсуждается StackOverflow с 2008 года:
Возможная замена в Модуль MooseX :: Method :: Signatures .
Как упоминается в другом ответе, $$
объявляет прототип. Другой ответ не говорит о том, для чего нужны прототипы. Они не предназначены для проверки ввода, это подсказки для парсера.
Представьте, что у вас объявлены две функции, например:
sub foo($) { ... }
sub bar($$) { ... }
Теперь, когда вы пишете что-то неоднозначное, например:
foo bar 1, 2
Perl знает, где поставить скобки; bar принимает два аргумента, поэтому потребляет два ближайших к нему. foo принимает один аргумент, поэтому принимает результат bar и два аргумента:
foo(bar(1,2))
Другой пример:
bar foo 2, 3
То же самое; foo принимает один аргумент, поэтому получает 2. bar принимает два аргумента, поэтому он получает foo (2)
и 3:
bar(foo(2),3)
Это довольно важная часть Perl, поэтому отклоняем ее как «никогда use "оказывает вам медвежью услугу. Практически каждая внутренняя функция использует прототипы, поэтому, понимая, как они работают в вашем собственном коде, вы можете лучше понять, как они используются встроенными командами. Тогда вы сможете избежать ненужных скобок, что сделает код более приятным.
Наконец, я предостерегаю вас от одного анти-шаблона:
package Class;
sub new ($$) { bless $_[1] }
sub method ($) { $_[0]->{whatever} }
Когда вы вызываете код как методы ( Class-> method
или $ instance-> method
), проверка прототипа совершенно бессмысленна. Если ваш код можно вызвать только как метод, добавлять прототип неправильно. Я видел несколько популярных модулей, которые делают это (привет, XML :: Compile
), но это неправильно, поэтому не делайте этого. Если вы хотите задокументировать, сколько аргументов нужно передать, как насчет:
sub foo {
my ($self, $a, $b) = @_; # $a and $b are the bars to fooify
....
или
use MooseX::Method::Signatures;
method foo(Bar $a, Bar $b) { # fooify the bars
....
В отличие от foo ($$)
, они значимы и удобочитаемы.