Perl子例程从实际参数中获取值的位置是什么?

时间:2014-09-25 15:25:51

标签: perl optional-parameters subroutine

我在追逐错误时遇到了以下Perl子例程get_billable_pages。它需要12个参数。

sub get_billable_pages {
    my ($dbc,
        $bill_pages,      $page_count,      $cover_page_count,
        $domain_det_page, $bill_cover_page, $virtual_page_billing,
        $job,             $bsj,             $xqn,
        $direction,       $attempt,
    ) = @_;

    my $billable_pages = 0;

    if ($virtual_page_billing) {
        my @row;
        ### Below is testing on the existence of the 11th and 12th parameters ###
        if ( length($direction) && length($attempt) ) {
            $dbc->xdb_execute("
                SELECT convert(int, value)
                FROM   job_attribute_detail_atmp_tbl
                WHERE  job             = $job
                AND    billing_sub_job = $bsj
                AND    xqn             = $xqn
                AND    direction       = '$direction'
                AND    attempt         = $attempt
                AND    attribute       = 1
            ");
        }
        else {
            $dbc->xdb_execute("
                SELECT convert(int, value)
                FROM job_attribute_detail_tbl
                WHERE job             = $job
                AND   billing_sub_job = $bsj
                AND   xqn             = $xqn
                AND   attribute       = 1
            ");
        }
        $cnt = 0;
        ...;

但有时只用10个参数调用

$tmp_det = get_billable_pages(
    $dbc2,
    $row[6],          $row[8],          $row[7],
    $domain_det_page, $bill_cover_page, $virtual_page_billing,
    $job1,            $bsj1,            $row[3],
);

该函数检查第11和第12个参数。

  • 当函数只传递10个参数时,第11个和第12个参数是什么?

  • 使用10个参数调用函数是一个错误,因为第11个和第12个参数最终是随机值?

  • 我认为这可能是错误的根源,因为第12个参数在程序失败时有一个时髦的值。

  • 我没有看到只有10个参数的函数的另一个定义。

2 个答案:

答案 0 :(得分:4)

将值从参数数组@_复制到标量变量列表中。

如果数组比列表短,则超出的变量设置为undef。如果数组长于列表,则忽略多余的数组元素。

请注意,分配不会修改原始数组@_。没有创建或丢失任何值,因此它仍然是调用子例程时传递的实际参数的权威来源。

ikegami 建议我提供一些Perl代码来演示将数组分配给标量列表。这是Perl代码,主要基于他的编辑

use strict;
use warnings;

use Data::Dumper;

my $x = 44;             # Make sure that we
my $y = 55;             # know if they change

my @params = (8);       # Make a dummy parameter array with only one value

($x, $y) = @params;     # Copy as if this is were a subroutine

print Dumper $x, $y;    # Let's see our parameters
print Dumper \@params;  # And how the parameter array looks

<强>输出

$VAR1 = 8;
$VAR2 = undef;

$VAR1 = [ 8 ];

因此 $x$y都会被修改,但如果数组中的值不足,则会使用undef。就好像源数组使用undef元素无限延长。

现在让我们看一下Perl代码的逻辑。出于条件测试的目的,undef评估为 false ,但您应用此length运算符

if ( length($direction) && length($attempt) ) { ... }

如果你有use warnings,Perl通常会产生Use of uninitialized value警告。但是length是不寻常的,如果您要求undef值的长度(并且您运行的是Perl 5的12或更高版本),它将返回undef而不是警告你。

关于&#34;我没有看到该函数的另一个定义,只有10个参数&#34; ,Perl没有像C ++和Java这样的函数模板 - 它已经启动了到子程序中的代码来查看它已经传递的内容并相应地表现。

答案 1 :(得分:2)

不,这不是一个错误。剩下的论点是&#34; undef&#34;你可以检查这种情况

sub foo {
    my ($x, $y) = @_;
    print " x is undef\n" unless defined $x;
    print " y is undef\n" unless defined $y;

}

foo(1);

打印

 y is undef