1

我有一种 perl “终端”(pastebin 代码),我们称之为我编写的,编写它背后的想法是我想逐行运行 perl 代码,允许我在现有的(大) 数据集,而无需更改脚本并重新加载数据集并重新运行我的脚本。

(请注意,我大约一年前写了这篇文章,它主要是一个学习实验(使用动态功能平板电脑),但是现在我对它有一些用处,并发现了一些阻碍我使用它的问题。)

因此,我eval用户输入了命令,但是,它们的行为与预期不同,也许有人可以解释为什么会这样。

这是“重要”位,我将命令行数据存储在 中@args,其中的第一个元素存储在$prog. 我检查是否存在现有函数(我允许用户创建函数,并且真的滥用引用来获取操作表)如果没有,我尝试评估命令。

if(exists($actions{$prog})){
        print "\n";
        $actions{$prog}->(@args);
        print "\n";
}else{
        print "\nEVALing '$command'\n";
        eval $command;
        warn $@ if $@;
        print "\n";
}

如下所示,它在分配标量时按预期工作,但在分配数组和散列时失败。

user@host:~/$ perl term.pl 
1358811935>$a = 0;
EVALing '$a = 0;'

1358811937>print $a;
EVALing 'print $a;'
0
1358811944>@b = qw(2 3);                                                                                                      
EVALing '@b = qw(2 3);'
Global symbol "@b" requires explicit package name at (eval 5) line 1.

1358811945>print @b;
EVALing 'print @b;'
Global symbol "@b" requires explicit package name at (eval 6) line 1.

1358812008>my @b = qw(2 3);                                                                                                   
EVALing 'my @b = qw(2 3);'

1358812008>print "@b";
EVALing 'print "@b";'
Possible unintended interpolation of @b in string at (eval 9) line 1.
Global symbol "@b" requires explicit package name at (eval 9) line 1.

1358812016>print join(',',@b);                                                                                                
EVALing 'print join(',',@b);'
Global symbol "@b" requires explicit package name at (eval 10) line 1.

1358812018>
4

2 回答 2

3

变量$a$b是特殊的,因为它们被sort. 因此,strict如果没有申报,也不会抱怨。使用$x会触发与数组和哈希相同的错误。

于 2013-01-21T23:54:22.697 回答
1

对于这种事情,您可能希望通过说来允许使用任意包变量no strict 'vars';。在 eval'd 代码中声明一个词法(我的)变量将起作用,但将不再在下一个 eval 的范围内。

或者,预先声明一组变量供 eval'd 代码使用(可能包括 %misc 哈希)。

一种完全不同的方法是每次通过 eval 连接到目前为止输入的所有代码(如果打印输出是一个因素,则将输出重定向到最近输入的代码)。

于 2013-01-22T00:00:59.880 回答