Что делает объявление функции “sub функция ($$)”, средний?

Я использовал Perl в течение некоторого времени, но сегодня я столкнулся с этим кодом:

sub function1($$)
{
   //snip
}

Что это означает в Perl?

6
задан Ether 21 March 2010 в 02:55
поделиться

2 ответа

Это функция с прототипом , которая принимает два скалярных аргумента.


Существуют веские аргументы в пользу того, чтобы вообще не использовать прототипы Perl - как указано в комментариях ниже. Самый сильный аргумент, вероятно, такой:

Там обсуждается StackOverflow с 2008 года:

Возможная замена в Модуль MooseX :: Method :: Signatures .

16
ответ дан 8 December 2019 в 03:52
поделиться

Как упоминается в другом ответе, $$ объявляет прототип. Другой ответ не говорит о том, для чего нужны прототипы. Они не предназначены для проверки ввода, это подсказки для парсера.

Представьте, что у вас объявлены две функции, например:

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 ($$) , они значимы и удобочитаемы.

11
ответ дан 8 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

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