【问题标题】:global symbol requires explicit package name.Error全局符号需要明确的包名。错误
【发布时间】:2017-11-06 05:41:55
【问题描述】:

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

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");

【问题讨论】:

  • @sborsky,你猜是use strict; use warnings qw( all );,即使在脚本中也经常被省略(因为它们应该总是存在)。
  • 感谢@ikegami,标题应该已经足够暗示了,收回我之前的评论。

标签: perl perl-module


【解决方案1】:

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

use warnings;
use strict;

另外,使用$a$b 是危险的,因为它们是用于sort 的全局变量。

my 变量 $a$b$res 是词法变量,但 sub 中的变量是其他全局变量;这是因为 sub 是在词法声明之前定义的。它们永远不会被初始化,所以它们的undefs 在返回时会覆盖词法。添加了use warnings;

在 .. [in sub] 的乘法 (*) 中使用未初始化的值 $b 在 .. [in sub] 处使用未初始化值 $a 进行乘法 (*) 在连接 (.) 中使用未初始化的值 $a 或在 .. 处使用字符串 [in print] 在连接 (.) 或字符串中使用未初始化的值 $b .. [in print]

sub 中的全局 $res 被初始化为 0 并且它的返回覆盖了词法的。

如果你将 sub 的代码放在最后,它会“工作”,因为词法在 sub 被编译之前被声明,所以 sub 看到它们并使用它们。但是话又说回来,如果词法在“动态”范围内也不起作用;见this post。总的来说,在 sub 中使用全局变量并不好。

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

然后它们仅存在于子中,也将可能的此类名称从外部范围屏蔽。 sub 有一个定义明确的接口,返回值(标量),你根据需要分配,一切都很清楚。

Private Variables via my() in perlsub


更新

标题暗示use strict; 已就位,并且有一条评论说明了这一点。那么问题将是关于变量的声明。

strict pragma 要求所有变量都被声明或完全限定。

sub 中的$res 没有声明,因此编译失败; $a$b 作为全局变量存在(但要与 sort 一起使用——为了方便,不要使用它们)。在包含的范围内可以看到声明的变量,但对于函数,这并不是那么简单,您希望在函数中声明所有变量。

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

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

【讨论】:

  • 我实际上包括严格和警告。我只得到了$res 的错误。那是因为 $a 和 $b 是豁免的全局变量。使用严格;使用警告;子乘 {my ($first, $second) = @_;my $res;$res = $first* $second;return ($res, ); } main: { 我的 $first =3;我的 $second =4;我的 $res; ($res) = 乘($first, $second); print ("Input1 = $first\nInput2 = $second\nResult = $res"); } 修改后的正确代码!
  • @keeru 是的,这是正确的方法,正如我在答案中所说的那样。但我不明白“我实际上包括严格和警告。而且我只有$res 出错。” - 很明显,程序无法编译,因为变量未声明而strict 已生效。我以为你在问发布代码的输出?
  • @keeru 再考虑你的评论,我添加了一个“更新”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-09
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多