为什么 Perl 的字符串 eval 中“pos”消失了?

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

这个简短的 Perl 脚本

my $var='$array', $val;

$val='val'; eval("push(\@{$var},$val)"); print"@{$array}[0]\n";
$val='pos'; eval("push(\@{$var},$val)"); print"@{$array}[1]\n";
$val='fun'; eval("push(\@{$var},$val)"); print"@{$array}[2]\n";

结果

val

fun

谁能解释一下,为什么

val
fun
被推到了
array
,而
pos
却没有?

我希望任何值都会被 eval 语句推送。

perl eval
2个回答
3
投票

第二个

eval
正在评估字符串
'push(@{$array},pos'
pos
是一个内置函数,它返回与正则表达式匹配相关的内容。由于脚本中尚未使用正则表达式,因此函数
pos
返回未定义的值。未定义的值被打印为空字符串。

裸词“val”和“fun”不是内置函数。因此它们被视为普通字符串。


2
投票

首先,始终使用

use strict; use warnings;
或同等内容。它会发现你所有的错误。


您正在评价

push(@{array},val);
push(@{array},pos);
push(@{array},fun);

没有

use strict;
,这相当于

push( @array, "val" );
push( @array, pos( $_ ) );
push( @array, "fun" );

val
fun
相当于
"val"
"fun"
,因为它们不可能有其他含义。然而,
pos
是与正则表达式匹配相关的内置函数。在此程序中,它返回
undef
,它被字符串化为空字符串。


您想要评估以下代码:

push( @array, $val )

要生成该字符串,您需要

"push( \@$var, \$val )"

所以使用

eval EXPR
,看起来像这样:

eval( "push( \@$var, \$val )" )

你错过了第二个

\
。 (你还有额外的卷发。这些确实有效,但最好避免这是一个未记录的功能。)

这是脆弱且危险的,使用

eval EXPR
是完全没有必要的。您可以使用以下内容:

{
   no strict 'refs';
   push( @$var, $val );
}

但是我们要求 Perl 阻止我们在每个程序中添加

use strict;
来阻止我们这样做是有原因的:这是一种非常非常糟糕的做法。您应该使用哈希值。

my %arrays;
push @{ $arrays{ $var } }, $val;
© www.soinside.com 2019 - 2024. All rights reserved.