重新定义子例程时没有足够的参数

bam*_*500 0 perl arguments subroutine

当我重新定义我自己的子程序(而不是Perl内置函数)时,如下所示:

perl -ce 'sub a($$$){} sub b {a(@_)}'
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

main :: a at -e line 1,"@_"附近的参数不够

我想知道为什么.

编辑:

"重新定义"这个词可能没有很好地选择.但在我的情况下(我可能应该已经解释了我原本想要做的事情),我想重新定义(并且这里"重新定义"有意义)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(@_);
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*oss 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);
}
Run Code Online (Sandbox Code Playgroud)

这个问题与你对原型的使用或你正在重新定义子程序这一事实无关(严格来说,你不是因为两个子程序在不同的包中),而是因为它Test::More::is()有一个原型.


sim*_*que 5

你不是在这里重新定义任何东西.

你设置了一个原型为您的子asub a($$$).函数定义中的美元符号告诉Perl该子函数正好有三个标量参数.当你调用它时a(@_),Perl不知道该列表中有多少个元素,因此它不知道调用将有多少个参数,并且在编译时失败.

不要乱用原型.你可能不需要它们.

相反,如果你知道你的sub需要三个参数,那么在你调用它的地方明确地抓住它们.

sub a($$$) {
    ...
} 

sub b {
    my ($one, $two, $three) = @_; 
    a($one, $two, $three);
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,根本不要使用原型.


此外,ab是可怕的名字.不要使用它们.

  • 我不认为问题是*"Perl不知道调用将有多少元素"*而是当需要三个调用时,调用只传递一个参数.像'a(@ _,@ _,@ _)这样的调用可以正常工作.每个参数在标量上下文中计算,并且等于`@ _`中的元素数. (3认同)