以下代码给出了一些奇怪的输出。任何人都可以解释这个问题吗?
use warnings;
my $P = 10;
print "My Var: $P\n";
display();
my $P = 12;
display();
sub display()
{
print "My Var: $P\n";
}
输出:
My Var: 10
My Var:
My Var: 12
答案 0 :(得分:4)
您应该提供脚本的完整输出:
"my" variable $P masks earlier declaration in same scope at P line 6.
main::display() called too early to check prototype at P line 4.
main::display() called too early to check prototype at P line 7.
My Var: 10
Use of uninitialized value in concatenation (.) or string at P line 11.
My Var:
My Var: 12
并阅读...答案在警告中......
如果您在脚本的开头添加use strict;
,则会收到其他警告:
main::display() called too early to check prototype at P line 5.
main::display() called too early to check prototype at P line 8.
这意味着在声明它之前用原型(在本例中为()
)调用子程序...
因此,首先声明子程序,或者更好的是,删除原型。
将您的代码更改为:
use strict;
use warnings;
my $P = 10;
print "My Var: $P\n";
display();
$P = 12;
display();
sub display
{
print "My Var: $P\n";
}
它的效果与你期望的一样 (但最好使用$ P作为子程序的参数......)
答案 1 :(得分:2)
首先,在Perl中,在调用子例程之前,不需要定义子例程;这样做会更好;因此你的代码会产生警告。但是,在这方面没有任何技术上的错误;这个警告也不是与你的问题有关。
我相信答案确实存在于你对“my”的同一个变量的两个声明中,再加上Perl解释器的特定行为。以下是perldiag:
对此警告的解释``my''变量%s屏蔽同一范围(S)A中的早期声明 词法变量已在同一范围内有效地重新声明 消除对先前实例的所有访问。这几乎总是如此 印刷错误。请注意,早期变量仍然存在 直到范围结束或直到所有关闭指示对象为止 破坏。
当你的print语句发生时,解释器只处理了$ P的第一个声明,因此它会打印出10,就像你期望的那样。
但是,当你调用sub时,Perl会去寻找子程序定义。它还必须找到它之前的所有其他变量声明,以便sub可以访问词法变量;它找到第二个声明,因此你的第一个$ P被新的$ P覆盖。但是,由于这个新的$ P尚未设置为程序中的任何内容,因此未定义。
答案 2 :(得分:0)
“my $ P”声明变量。你做了两次,你也应该得到一个错误。改变“我的$ P = 12;”到“$ P = 12;”你会得到你想要的东西。
我建议你在perl上阅读一下(看看“perldoc perl”和“perldoc perlintro”,或http://www.perl.org/learn.html)
答案 3 :(得分:-1)
my $P = 12;
您已经在上面声明了$ P(my $P = 10;
),并且不应该再次执行此操作,请删除my,
display();
调用子例程:&display();