我有
a module使用@INC钩子并试图安装丢失的模块,因为它们被使用.我不希望这种行为在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中运行可能对信息目的有所帮助,但由于这可能由于许多不同的原因而发生,因此很难推断它为什么会发生
>无论如何,这是一项有趣的练习.我感谢所有贡献者的有益投入
解决方法
如果这样可以让事情变得更容易,Carp :: longmess会在一次调用中遍历堆栈
return if Carp::longmess =~ m{^\s+eval }m