如何将可选参数传递给Perl子例程?

时间:2016-07-19 10:38:42

标签: perl parameters arguments parameter-passing optional-parameters

我想将两个参数传递给我的子程序。第一个参数是必需的,第二个参数我想是可选的。实际上它适用于此脚本中的非数组参数:

            deftest ("string value test",9);

            sub deftest{
                my ($strvalue, $num) = @_;
                if (defined $num){
                    print "\nCHECK 1 - Defined value $num";
                } else {
                    $num //= 99;
                }
                print "\nstrvalue: $strvalue num: $num\n";
            }

当我用(“字符串值测试”,9)调用此子例程时;然后在屏幕上:
CHECK 1 - Defined value 9 strvalue: string value test num: 9

当我没有输入第二个参数时,则值为99.所以这样可以正常工作。

问题是,当我在第一个参数中使用数组时:

            my @arrSwap = (1,2,3);
            deftest2 (@arrSwap,5);

            sub deftest2{
                my (@arrSwap, $num) = @_;
                if (defined $num){
                    print "\n\nCHECK 2 - Defined val $num";
                } else {
                    $num //= 55;
                }
                print "\narrSwap $arrSwap[1] num: $num\n";
            }

用deftest2调用这个子程序后(@ arrSwap,5);然后在屏幕上我只有:arrSwap 2 num: 55  (但是在定义时可以预期5个。)

为什么它不适用于数组?

3 个答案:

答案 0 :(得分:3)

因为perl将单个列表作为参数传递,并且分配my ( @arrSwap, $num ) = @_ 总是意味着空$num,因为@arrSwap将消耗整个输入。

如果你想这样做,你需要传递一个参考

    my @arrSwap = ( 1,2,3 ); 
    deftest2 ( \@arrSwap, 5);  

    sub deftest2 { 
        my ( $arrSwap_ref, $num ) = @_; 
        $num //= 55;
        print "\narrSwap", $arrSwap -> [1], " num: $num\n";
    }

否则perl根本无法判断最后一个数字是否是您发送的列表的一部分,或者是一个可选参数。

答案 1 :(得分:2)

子例程的参数是Perl中的列表。将参数分配给数组时,Perl不知道该数组应该有多长,因此无法执行此操作:

sub frobnicate {    
    my (@foo, $bar) = @_;
}

在这种情况下,$bar始终为undef,因为它只是将列表的其余部分分配给@foo

相反,您需要将参数的数组部分作为引用,并正确地对其进行反驳。

sub frobnicate {
    my ($foo, $bar) = @_;

    foreach my $element (@{ $foo }) {
        # ...
    }
}

然后用引用来调用它。

frobnicate(\@foo, 123);

因为引用是标量值,所以现在您知道参数列表中有多少个元素,并且您可以在列表的末尾添加可选参数。

答案 2 :(得分:2)

数组在参数列表中展开,形成前N个参数,最后出现$num

如果以这种方式传递数组,则无法从子例程中判断出数组中有多少参数,因此最好通过 reference 传递数组

您的代码看起来像这样

my @arrSwap = ( 1, 2, 3 );

deftest2( \@arrSwap, 5 );
deftest2( \@arrSwap );

sub deftest2 {
    my ( $arrSwap, $num ) = @_;

    if ( defined $num ) {
        print "\n\nCHECK 2 - Defined val $num";
    }
    else {
        $num = 55;
    }
    print "\narrSwap $arrSwap->[1] num: $num\n";
}

输出

CHECK 2 - Defined val 5
arrSwap 2 num: 5

arrSwap 2 num: 55