我猜想这对那些了解Perl的人来说应该是显而易见的,但是我根本不了解它。我也猜想这与Perl scoping « darkness中描述的问题有关,但是我不能在我的情况下应用任何问题。
无论如何,这是代码:
#!/usr/bin/env perl
# call with:
# ./test.pl
use strict;
my $tvars = "my \$varA = 1;
my \$varB = 2;
my \$varC = 3;
";
my @lines = split /\n/, $tvars;
foreach my $line (@lines) {
print "$line\n";
eval $line; warn $@ if $@;
}
#~ print "$varA\n"; # Global symbol "$varA" requires explicit package name at ./test.pl line 18.
#~ print "$varB\n"; # Global symbol "$varB" requires explicit package name at ./test.pl line 19.
#~ print "$varC\n"; # Global symbol "$varC" requires explicit package name at ./test.pl line 20.
$tvars = "our \$varA = 1;
our \$varB = 2;
our \$varC = 3;
";
@lines = split /\n/, $tvars;
foreach my $line (@lines) {
print "$line\n";
eval $line; warn $@ if $@;
}
print "$varA\n"; # Global symbol "$varA" requires explicit package name at ./test.pl line 33.
print "$varB\n"; # Global symbol "$varB" requires explicit package name at ./test.pl line 34.
print "$varC\n"; # Global symbol "$varC" requires explicit package name at ./test.pl line 35.
简而言之,我想将类似“$varA = 1;
”的内容写成字符串(文本文件);并且我希望perl
对其进行eval
编码,以便以后我可以在同一脚本中访问变量“$varA
”-尝试在eval
之后访问变量时遇到的错误在上面的代码注释中(但是, eval
期间未报告任何警告)。 (我猜想,如果eval
在与主脚本不同的上下文中运行,我需要的是诸如“全局”变量之类的东西?)我将如何去做?我是否必须经历所有的包定义业务,即使是像上面这样的简单脚本也是如此?
最佳答案
它与范围界定有关。在eval表达式中使用my
声明变量。这使它们在eval
语句本地,并且一旦eval
语句退出就无法访问。不过,您可以先声明它们:
my ($varA, $varB, $varC); # declare outside the eval statement
my $tvars = "\$varA = 1;
\$varB = 2;
\$varC = 3;
";
eval $tvars;
# local $varA, $varB, $varC variables are now initialized
或者按照您的建议,可以使用全局变量。最简单(尽管不一定是“最佳”方法)是在所有变量名前添加
::
并将其放入主包中。my $tvars = "\$::varA = 1;
\$::varB = 2;
\$::varC = 3;
";
eval $tvars;
print "A=$::varA, B=$::varB, C=$::varC\n";
现在,当您在示例中尝试
our
变量时,实际上是在初始化程序包(全局)变量。但是在eval
语句之外,您仍然需要限定(即,指定程序包名称)它们才能访问它们:$tvar = "our \$foo = 5";
eval $tvar;
print $main::foo; # ==> 5
关于perl - 使用eval初始化Perl变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7506782/