当我重新定义我自己的子程序(而不是Perl内置函数)时,如下所示:
perl -ce 'sub a($$$){} sub b {a(@_)}'
我收到此错误:
没有足够的参数为main :: a at -e line 1,near" @_)"
我想知道为什么。
编辑:
"重新定义"可能没有很好的选择。但在我的情况下(我可能应该已经解释了我原本想要做的事情),我想重新定义(并且这里"重新定义"有意义)Test :: More ::是首先打印的功能测试结果前的日期和时间。
这就是我所做的:
Test::More.pm :
sub is ($$;$) {
my $tb = Test::More->builder;
return $tb->is_eq(@_);
}
MyModule.pm :
sub is ($$;$) {
my $t = gmtime(time);
my $date = $t->ymd('/').' '.$t->hms.' ';
print($date);
Test::More::is(@_);
}
答案 0 :(得分:7)
您为子程序提供的原型(从Test::More::is
复制)表示您的子程序需要两个必需参数和一个可选参数。传入单个数组将无法满足该原型 - 它被视为将在标量上下文中进行评估的单个参数。
修复方法是检索传递给子例程的两个(或三个)参数,并将它们分别传递给Test::More::is
。
sub is ($$;$) {
my ($got, $expected, $test_name) = @_;
my $t = gmtime(time);
my $date = $t->ymd('/').' '.$t->hms.' ';
print($date);
Test::More::is($got, $expected, $test_name);
}
这个问题与你使用原型无关,或者你正在重新定义子程序这一事实(严格来说,你不是因为这两个子程序在不同的包中),但是它不是这样的。因为Test::More::is()
有原型。
答案 1 :(得分:5)
你不是在这里重新定义任何东西。
您通过说a
为您的子sub a($$$)
设置了prototype。函数定义中的美元符号告诉Perl该子函数正好有三个标量参数。当你用a(@_)
调用它时,Perl不知道该列表中有多少个元素,因此它不知道调用将有多少个参数,并且在编译时失败。
不要乱用原型。你可能不需要它们。
相反,如果你知道你的sub需要三个参数,请在你调用它的地方明确地抓住它们。
sub a($$$) {
...
}
sub b {
my ($one, $two, $three) = @_;
a($one, $two, $three);
}
或者更好的是,根本不要使用原型。
此外,a
和b
是可怕的名字。不要使用它们。
答案 2 :(得分:4)
在Perl中,原型不会像修改解析规则那样验证参数。 $(document).on('click', '.className', function(){ //do stuff});
表示子要求来电者与$$;$
或is(EXPR, EXPR)
匹配。
在这种情况下,绕过原型是理想的。
is(EXPR, EXPR, EXPR)
由于您并不关心sub is($$;$) {
print gmtime->strftime("%Y/%m/%d %H:%M:%S ");
return &Test::More::is(@_);
}
是否会修改您的Test::More::is
,因此以下是一项简单的优化:
@_
如果sub is($$;$) {
print gmtime->strftime("%Y/%m/%d %H:%M:%S ");
return &Test::More::is;
}
使用Test::More::is
,您会发现以下内容非常有用:
caller