如何检测一个词法变量是否存在于包中(已声明),即使是未初始化的?

问题描述 投票:0回答:1

比方说,我有一些

package Foo;
my $bar;

我怎么才能知道是否 $bar 被声明,而不管它是否未初始化?

在某种程度上,我认为这是有可能的,因为...。warnings 知道了warnings 知音 $bar 存在,所以你得到的只是一个未初始化的警告。

$ perl -wE'my $bar; print $bar;'
Use of uninitialized value $bar in print at -e line 1.

但是 once 警告类在这里知道,变量 $baz 甚至没有宣布。

$ perl -wE'my $bar; print $baz;'
Name "main::baz" used only once: possible typo at -e line 1.
Use of uninitialized value $baz in print at -e line 1.

同样。strict 就会停止编译,所以它也必须知道这一点(注意到 die 从来没有触发过)。)

$ perl -wE'use strict; my $bar; print $baz; die 42;'
Global symbol "$baz" requires explicit package name (did you forget to declare "my $baz"?) at -e line 1.
Execution of -e aborted due to compilation errors.

所以它也必须知道这一点。

perl variables variable-declaration
1个回答
3
投票

PadWalker 可以检查哪些词法变量被定义了。

use PadWalker ':all';
my $foo;

my $level = -1;
while (my $pad = eval { peek_my(++$level) }) {
    print "$_ is declared in scope $level\n" for keys %$pad;
}

$level is defined in scope 0
$foo is defined in scope 0

2
投票

而不需要Padwalker(打印一次 "is lex")。

package Foo;

print "is lex\n" if eval('\\$' . __PACKAGE__ . '::foo') != \$foo;
my $foo;
print "is lex\n" if eval('\\$' . __PACKAGE__ . '::foo') != \$foo;

2
投票

要说明的是,词汇变量并不是任何包的一部分 也不会与包系统有任何互动,这是一个完全不同的会计。不管任何包声明,它都属于它所在的范围。这个作用域要么是括号,要么是声明它的子程序,要么是文件。

你所展示的大多数例子(oncestrict)处理包变量。对于这一点,你可以直接在stash中查看是否定义了这个名字。

对于未初始化的情况,perl在尝试使用该变量时,会看到它没有值。


2
投票
package Foo;
my $x;
my $eval_fmt = 'use strict; %s || 1';
eval( sprintf $eval_fmt, '$y' ) or warn 'No such variable: $y';
eval( sprintf $eval_fmt, '$x' ) and warn 'Variable $x exists';
© www.soinside.com 2019 - 2024. All rights reserved.