6

我使用 Perl 已经有一段时间了,但是今天我遇到了这段代码:

sub function1($$)
{
   //snip
}

这在 Perl 中意味着什么?

4

2 回答 2

16

它是一个带有带有两个标量参数的原型的函数。


通常不实际使用 Perl 原型有很强的论据 - 正如下面的评论中所指出的。最有力的论据可能是:

从 2008 年开始有关于 StackOverflow 的讨论:

MooseX::Method::Signatures模块中有一个可能的替代品。

于 2010-03-20T22:46:02.283 回答
11

正如另一个答案所提到的,$$声明了一个原型。另一个答案没有说的是原型的用途。它们不是用于输入验证,它们是解析器的提示。

想象一下,您有两个函数声明如下:

sub foo($)  { ... }
sub bar($$) { ... }

现在当你写一些模棱两可的东西时,比如:

foo bar 1, 2

Perl 知道把括号放在哪里;bar 需要两个参数,因此它消耗最接近它的两个参数。foo 需要一个 arg,所以它需要 bar 和两个 args 的结果:

foo(bar(1,2))

另一个例子:

bar foo 2, 3

这同样适用;foo 需要一个 arg,所以它得到 2。 bar 需要两个 arg,所以它得到foo(2)3:

bar(foo(2),3)

这是 Perl 的一个非常重要的部分,因此将其视为“从不使用”是对您的伤害。几乎每个内部函数都使用原型,因此通过了解它们在您自己的代码中的工作方式,您可以更好地了解内置函数如何使用它们。然后你可以避免不必要的括号,这使得代码看起来更愉快。

最后,我会警告你一种反模式:

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($$)的是,这些是有意义且可读的。

于 2010-03-21T02:04:48.127 回答