我有一个使用@INC钩子的模块,并试图安装丢失的模块,因为它们是used.我不希望这种行为在内部触发eval.我目前的尝试是:
return
if ( ( $caller[3] && $caller[3] =~ m{eval} )
|| ( $caller[1] && $caller[1] =~ m{eval} ) );
Run Code Online (Sandbox Code Playgroud)
这是我在一些实验中乱用调用堆栈的结果,但它没有捕获所有内容,例如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";
}
Run Code Online (Sandbox Code Playgroud)
也许我只需要遍历调用堆栈的每个级别,直到我达到eval或超出级别.有没有更好或更简单的方法来判断代码是否在eval没有遍历调用堆栈的情况下被包装?
在这个问题上验尸:
$^S从技术上讲,这是一种正确的方法,但它不会让你知道你是否在一个eval被称为堆栈中更高的地方Carp::longmess()似乎是最简洁的方法来解决这个问题eval可能对信息目的有所帮助,但由于这可能由于许多不同的原因而发生,因此很难推断它为什么会发生如果$^S为 true,则代码位于eval.
sub foo { print $^S }
eval { foo() }; # 1
foo(); # 0
Run Code Online (Sandbox Code Playgroud)
Carp::longmess 在一次调用中遍历堆栈,如果这样可以使事情变得更容易
return if Carp::longmess =~ m{^\s+eval }m
Run Code Online (Sandbox Code Playgroud)