sud*_*03r 6 perl prototype subroutine
我已经使用Perl一段时间了,但今天我遇到了这段代码:
sub function1($$)
{
//snip
}
Run Code Online (Sandbox Code Playgroud)
这在Perl中意味着什么?
Jon*_*ler 16
它是一个带有两个标量参数的原型函数.
对于实际上没有实际使用Perl原型有强有力的论据 - 如下面的评论中所述.最强烈的论点可能是:
从2008年开始讨论StackOverflow:
MooseX :: Method :: Signatures模块中可能存在替换.
jro*_*way 11
正如另一个答案所提到的那样,$$声明了一个原型.另一个答案没有说的是原型的用途.它们不用于输入验证,它们是解析器的提示.
想象一下,你有两个声明的函数:
sub foo($) { ... }
sub bar($$) { ... }
Run Code Online (Sandbox Code Playgroud)
现在当你写一些含糊不清的东西时,比如:
foo bar 1, 2
Run Code Online (Sandbox Code Playgroud)
Perl知道在哪里放置parens; bar需要两个args,所以它会消耗最接近它的两个args.foo需要一个arg,所以它需要bar和两个args的结果:
foo(bar(1,2))
Run Code Online (Sandbox Code Playgroud)
另一个例子:
bar foo 2, 3
Run Code Online (Sandbox Code Playgroud)
同样适用; foo需要一个arg,所以得到2. bar需要两个args,所以得到foo(2)3个:
bar(foo(2),3)
Run Code Online (Sandbox Code Playgroud)
这是Perl非常重要的一部分,因此将其视为"永不使用"会对您造成伤害.几乎每个内部函数都使用原型,因此通过了解它们在您自己的代码中的工作方式,您可以更好地理解内部函数如何使用它们.然后你可以避免不必要的括号,这使得代码更加令人愉悦.
最后,一个反模式我将警告你反对:
package Class;
sub new ($$) { bless $_[1] }
sub method ($) { $_[0]->{whatever} }
Run Code Online (Sandbox Code Playgroud)
当您将代码作为方法(Class->method或$instance->method)调用时,原型检查完全没有意义.如果您的代码只能作为方法调用,则添加原型是错误的.我见过一些流行的模块(hello,XML::Compile),但这是错的,所以不要这样做.如果你想记录要通过的args数量,那么:
sub foo {
my ($self, $a, $b) = @_; # $a and $b are the bars to fooify
....
Run Code Online (Sandbox Code Playgroud)
要么
use MooseX::Method::Signatures;
method foo(Bar $a, Bar $b) { # fooify the bars
....
Run Code Online (Sandbox Code Playgroud)
不同foo($$),这些是有意义和可读的.