如何检测Perl代码是否在eval中运行?

时间:2018-07-23 16:19:47

标签: perl

我有a module,它使用@INC钩子并尝试安装use d丢失的模块。我不希望在eval内部触发此行为。我目前的尝试是:

return
    if ( ( $caller[3] && $caller[3] =~ m{eval} )
    || ( $caller[1] && $caller[1] =~ m{eval} ) );

那是我在某些实验中弄乱了调用堆栈的结果,但并没有捕获所有内容,例如HTTP::Tinyish中的代码:

sub configure_backend {
    my($self, $backend) = @_;
    unless (exists $configured{$backend}) {
        $configured{$backend} =
          eval { require_module($backend); $backend->configure };
    }
    $configured{$backend};
}

sub require_module {
    local $_ = shift;
    s!::!/!g;
    require "$_.pm";
}

也许我只需要遍历调用堆栈的每个级别,直到达到eval或级别用完为止。对于我来说,是否有更好或更简单的方法可以确定代码是否被包装在eval中而无需遍历调用堆栈?


对此问题进行验尸:

  • 正如多名海报所建议的那样,这基本上是一个坏主意
  • $^S从技术上来说是一种正确的方法,但是它不会让您知道自己是否位于栈中较高位置的eval
  • 使用正则表达式+ Carp::longmess()似乎是最简洁的方法
  • 知道代码是否在eval中运行可能出于信息目的而有所帮助,但是由于这可能由于多种原因而发生,因此很难推断其发生原因
  • 不管,这都是一个有趣的练习。我感谢所有贡献者的有益帮助

3 个答案:

答案 0 :(得分:5)

Carp::longmess在一个调用中为您遍历堆栈,如果这样会使事情变得更容易

return if Carp::longmess =~ m{^\s+eval }m

答案 1 :(得分:4)

如果$^S为真,则代码在echo ${LINE} | cut -d' ' -f2 | sort -u | uniq内部。

eval

答案 2 :(得分:3)

请勿尝试在可重用的代码中执行此操作。评估有很多原因,并且不希望在远距离改变时采取这种措施。