输出对于我的类型声明无效

时间:2012-08-09 11:27:51

标签: perl perl-module mod-perl

以下代码给出了一些奇怪的输出。任何人都可以解释这个问题吗?

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

4 个答案:

答案 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();