全局符号需要显式包名称.错误

kee*_*eru 2 perl perl-module

如果我将变量作为全局变量,它可以正常工作.这段代码有什么问题?

sub Multiply {
    $res = $a* $b;
    return ( $a, $b, $res);
}

main: 
my $a =3;
my $b =4;
my $res;
( $a, $b, $res) = Multiply();
print ("Input1 = $a\nInput2 = $b\nResult = $res");
Run Code Online (Sandbox Code Playgroud)

zdi*_*dim 6

最重要的错误是你没有声明变量而没有变量

use warnings;
use strict;
Run Code Online (Sandbox Code Playgroud)

此外,使用$a$b是危险的,因为它们是全局的意思sort.

my变量$a,$b,$res是词汇,但在子的那些还没有其他的,全局变量; 这是因为sub是在声明词法之前定义的.它们从未被初始化,所以它们undef在返回时会覆盖词汇.随着use warnings;加入

Use of uninitialized value $b in multiplication (*) at ..           [in sub]
Use of uninitialized value $a in multiplication (*) at ..           [in sub]
Use of uninitialized value $a in concatenation (.) or string at ..  [in print]
Use of uninitialized value $b in concatenation (.) or string at ..  [in print]

$ressub中的全局被初始化为,0并且其返回将覆盖词法中的全局.

如果你把代码分在最后这将"工作",因为词法得到之前被编译的子这样子看到他们,并可以使用它们声明.但话又说回来,如果词汇处于"动态"范围内,那么它们也无法发挥作用; 看这篇文章.

只需在子例程中声明变量并将其传递给它所需的内容.

然后它们只存在于sub中,也从外部范围中屏蔽这些名称.sub有一个定义良好的接口,返回你根据需要分配的值(标量),一切都很清楚.

通过perlsub中的my()查看私有变量


更新

标题暗示use strict;到位,并且评论说明了这一点.然后问题是关于变量的声明.

严格的编译要求,除一些其他的东西,所有的变量声明或完全合格的.

$res在子未声明,因此编译失败; 在$a$b存在的全局(但对于使用sort-不使用它们为了方便).声明的变量在包含的作用域中可见,但是对于函数,这并不是那么简单,并且您希望在函数内声明所有变量.

我们声明的类似全局变量是可以的,但它们的使用会带来其他问题.虽然偶尔使用全局变量很少需要它们并且最好避免使用,因为它们的使用会破坏干净的范围,这是编程中的关键原则之一.

一个有用的参考是perldiag,它解释了错误消息.或者,在调试运行中使用诊断程序,或者更好地使用splain或运行代码perl -Mdiagnostics ...