0

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

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

4 回答 4

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 作为子例程的参数......)

于 2012-08-09T12:05:36.323 回答
2

首先,在 Perl 中,您不需要在调用子程序之前定义它;这样做会更好;因此您的代码会产生警告。但是,在这方面技术上并没有错。此警告也与您的问题无关。

我相信答案确实在你用“my”对同一个变量的两个声明中,再加上 Perl 解释器的具体行为。以下是perldiag对这个警告的解释:

``my'' 变量 %s 掩盖了同一范围内的先前声明 (S) 已在同一范围内重新声明了一个词法变量,从而有效地消除了对先前实例的所有访问。这几乎总是一个印刷错误。请注意,较早的变量将仍然存在,直到作用域结束或所有指向它的闭包对象都被销毁。

当您的 print 语句发生时,解释器仅处理了 $P 的第一个声明,因此它打印 10,正如您所期望的那样。

However, when you call the sub, Perl goes to look for the subroutine definition. It also has to find all of the other variable declarations preceding it, so that the sub can have access to lexical variables; it finds the second declaration, and thus your first $P is overwritten with a new $P. However, since this new $P hasn't been set to anything yet in your program, it is undefined.

于 2012-08-09T13:00:05.773 回答
0

"my $P" 声明变量。你这样做了两次,你也应该得到一个错误。更改“我的 $P = 12;” 到“$P = 12;” 你会得到你想要的。

我建议您阅读一些关于 perl 的内容(查看“perldoc perl”和“perldoc perlintro”,或http://www.perl.org/learn.html

于 2012-08-09T11:36:17.167 回答
-1

my $P = 12; 您已经在上面声明了 $P( my $P = 10;),不应该再这样做了,删除 my,
display();像这样调用子例程:&display();

于 2012-08-09T11:34:53.953 回答