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

时间:2017-11-06 05:41:56

标签: 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");

1 个答案:

答案 0 :(得分:5)

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

use warnings;
use strict;

此外,使用$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]

sub中的全局$res被初始化为0,其返回值将覆盖词法。

如果你要将sub的代码放在最后,它将会工作,"因为lexicals在编译sub之前被声明,所以sub看到它们并且可以使用它们。但话说回来,如果词汇中的词汇是动态的,那就是"范围也不会起作用;见this post

只需在子程序中声明变量并将变量传递给它。

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

请参阅Private Variables via my() in perlsub

<强>更新

标题提示use strict;到位,评论指出。然后问题是关于变量的声明。

strict pragma要求在所有其他事项中声明所有变量或完全限定。

子语句中的$res未声明,因此编译失败; $a$b作为全局变量存在(但与sort一起使用 - 为方便起见,请不要使用它们)。声明的变量在包含的范围中可见,但是使用函数时,这并不是很简单,并且您希望在函数内声明所有变量。

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

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