Perl:在线程中使用eval时为空变量

时间:2014-09-30 09:33:28

标签: multithreading perl eval

我在将项目从perl 5.8.8更新到perl 5.18.2时遇到了问题 我已将问题简化为以下示例:

use threads;

my $key = "abcdef";

print "test1 key = $key.\n";

my $thr = threads->create(sub {
    eval "print \"test2 key = \$key.\n\";";
}); 

$thr->join();

在perl 5.8.8中,这给出了正确的输出:

test1 key = abcdef.
test2 key = abcdef.

但是对于perl 5.18.2,我有:

test1 key = abcdef.
test2 key = .

我已经尝试了其他perl版本,问题似乎已经出现在5.14.0版本中。 我正在寻找纠正这个问题的最佳方法,以及关于perl beaviour修改的解释。

我找到了一些替代方案,但它们似乎都不适合我:

  • 使用“我们的$ key”而不是“my $ key”;但这使变量“更公开”
  • 添加“my $ toto = $ key;”在eval行之前(仍然在eval行中使用$ key);事实上,在eval线之前用$ key做某事(打印,做作,使用......)似乎解决了这个问题。但增加的线对于该功能是无用的。

在eval命令中使用$ key而不是\ $ key对我来说不是一个解决方案,因为在实际程序中我将处理更复杂的结构。

2 个答案:

答案 0 :(得分:4)

问题与线程无关。查看类似的PerlMonks主题。要创建闭包,编译器需要知道将使用的变量。您只需提及要关闭的子变量:

my $thr = threads->create(sub {
    $key;  # Create a closure.
    eval "print \"test2 key = \$key.\n\";";
}); 

要查看类似的非线程情况,只需创建范围:

my $sub = do {
    my $key = "abcdef";
    print "test1 key = $key.\n";
    sub {
        $key; # <-- Comment this line to get no value.
        eval "print \"test2 key = \$key.\n\";";
    }
};

$sub->();

答案 1 :(得分:0)

Perl有两个名为eval的函数。

  • eval EXPR解析并执行Perl代码。

  • eval BLOCK是一个异常陷阱。这通常在其他语言中称为try

使用正确的功能可以解决您的问题,因为它不会尝试使用不再存在的变量。