为什么 T::fn2 有两个参数调用时只有一个参数?

Why T::fn2 has only one parameter when it was called with two arguments?

我有下一个剧本:

package T;
use strict;
use warnings;

sub fn1 {
    my( $var1, $var2 ) =  @_;
    T::fn2 $var1, $var2;
}

sub fn2 {
    print ">>@_<<"; # >>x1<<
}

package main;
use strict;
use warnings;

T::fn1 'x1', 'x2'; # >>x1<<

这里调用 T::fn2 有两个参数,但它只得到一个参数。

我知道我调用了前向子程序,该子程序在解析时不可见并且被算作裸字。

但我有 use strictuse warnings,所以我预计会发出警告,或者程序根本无法运行,而是无法正常运行。

所以 为什么它仍然有效并且 T::fn2 实际上是用一个参数调用的?

perl 版本为 5.30.3

运行

perl -MO=Deparse,-p

看看编译器是如何理解代码的:

sub fn1 {
    (my($var1, $var2) = @_);
    ($var1->T::fn2, $var2);
}

因此,调用被解释为方法调用的间接对象表示法,而子例程returns有两个值:方法调用的结果和$var2.


要使其正常工作,您有两种选择:

  1. 在子例程参数周围使用括号

    T::fn2($var1, $var2);

  2. 确保函数在调用前声明

sub fn2 {
    print ">>@_<<";
}

sub fn1 {
    my ($var1, $var2) =  @_;
    T::fn2 $var1, $var2;
}
  1. 确保函数在调用之前声明(前向声明)
sub fn2;

sub fn1 {
    my ($var1, $var2) =  @_;
    T::fn2 $var1, $var2;
}

sub fn2 {
    print ">>@_<<";
}