为什么此代码无法正常运行?我试图编写代码来打印每个数组的最后一个值,看起来我只是用不同的变量名一遍又一遍地写相同的行。然后我尝试做这样的事情,我可以采取一个循环让它为我构建变量名称,然后评估它就像它是真正的Perl一样。但是当我尝试将它视为数组时,数组无法初始化并抛出错误。
现在,也许我对'eval'的使用感到困惑。但似乎这应该有效,而且我有点难过。我究竟做错了什么?我需要告诉perl评估“@a”(或者我所在的任何一个)并返回@a。
#!/usr/bin/perl -w
use strict;
my @a = (1, 2, 3);
my @b = (4, 5, 6);
my @c = (7, 8, 9);
my @letters = ('a'..'c');
foreach (@letters) {
my $varname = '@' . "$_"; ## Generate the variable name I want to use. Returns '@a' or '@b' or '@c' just fine.
my @foo = eval { $varname }; ## Only returns '@a' or '@b' or '@c' again. =\
foreach (@foo) {
print 'The last element of the array is: ' . $foo[-1] . "\n"; ## returns only the array name. e.g. '@a' See previous comment.
}
}
如果我没弄错的话,这个程序的正确输出应该是36912。
答案 0 :(得分:2)
您需要eval $varname
,而不是eval { $varname }
。
但请阅读Why it's stupid to `use a variable as a variable name'。
最好是使用引用 - 例如:
#!/usr/bin/env perl
use strict;
use warnings;
my @a = (1, 2, 3);
my @b = (4, 5, 6);
my @c = (7, 8, 9);
my @all = (\@a, \@b, \@c);
foreach (@all) {
my @foo = @$_;
foreach (@foo) {
print "The last element of the array is: $foo[-1]\n";
}
}
答案 1 :(得分:0)
您可以通过阅读eval
的文档来解释您的问题,因为您使用的是第二个表单而不是第一个表单:
eval EXPR
eval BLOCK
eval
在第一种形式中,
EXPR
的返回值被解析并执行,好像它是一个小的Perl程序。首先解析表达式的值(它本身在标量上下文中确定),如果没有错误,则作为当前Perl程序的词汇上下文中的块执行。这意味着,特别是任何外部词法变量都是可见的,之后任何包变量设置或子例程和格式定义都会保留。...
在第二种形式中,BLOCK中的代码只被解析一次 - 同时解析eval本身周围的代码 - 并在当前Perl程序的上下文中执行。此表单通常用于比第一个表单更有效地捕获异常(见下文),同时还提供了在编译时检查BLOCK中的代码的好处。
基本上,my @foo = eval { $varname };
等同于my @foo = do { $varname };
,但它会进行错误捕获。显然,虚空上下文中的简单标量不会引发任何错误,因此它等同于my @foo = $varname;
。
如果你想要另一个,你必须使用my @foo = eval "$varname";
无论如何,你根本不应该使用eval
。它不是初学者程序员必备的工具,只会让你遇到麻烦。 {@ 1}}初学者可接受的唯一时间是正则表达式的RHS,eval
因此,请遵循tobyink的建议并使用参考资料。