Reputation: 5279
I've got a module that uses an @INC
hook and tries to install missing modules as they are use
d. I don't want this behaviour to fire inside an eval
. My attempt to do this currently is:
return
if ( ( $caller[3] && $caller[3] =~ m{eval} )
|| ( $caller[1] && $caller[1] =~ m{eval} ) );
That's the result of me messing around with the call stack in some experiments, but it's not catching everything, like this code in 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";
}
Maybe I just need to traverse every level of the call stack until I hit an eval
or run out of levels. Is there a better or easier way for me to figure out whether or not code is being wrapped in an eval
without traversing the call stack?
Post mortem on this question:
$^S
is technically a correct way to do this, but it doesn't let you know if you're inside an eval
that was called somewhere higher in the stackCarp::longmess()
seems to be the most concise way to figure this outeval
may be somewhat helpful for informational purposes, but since this could be happening for many different reasons, it's very hard to infer why it's happeningUpvotes: 7
Views: 284
Reputation: 98388
Don't try to do this in reusable code. There are many reasons to be in an eval and not want this kind of action at a distance change.
Upvotes: 3
Reputation: 118605
Carp::longmess
traverses the stack for you in one call, if that makes things easier
return if Carp::longmess =~ m{^\s+eval }m
Upvotes: 5