rockyb has asked for the wisdom of the Perl Monks concerning the following question:

In the Devel::Trepan debugger (or possibly other debuggers), the debugger fakes up the environment before calling eval() to show values of expressions that a user might try. Specifically, Devel::Trepan fakes the values of @_, __FILE__, __LINE__ to reflect the values in the debugged program rather than the real current values inside the debugger environment.

What I'd like to do is replace CORE::caller() or just caller() inside the eval with my own custom routine which will pop off the top calls from inside the debugger.

Of course, it would be good to restore those values after the eval() although I suppose my custom one could work all the time doing essentially nothing when not in the debugger.

Any thoughts?


Replies are listed 'Best First'.
Re: How/can one to save/restore CORE::caller inside an eval?
by tobyink (Canon) on Dec 03, 2013 at 22:34 UTC
    use v5.12; # This is basically a dummy override that must be performed early # on so that Perl knows we'll be overriding CORE::GLOBAL::caller # later... # BEGIN { *CORE::GLOBAL::caller = sub { CORE::caller(@_) } }; sub foo { say scalar caller; } sub bar { local *CORE::GLOBAL::caller = sub { 'xxxx' }; foo(); } foo(); bar();
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

      This is fantastic — almost. The first problem I have is that adding the BEGIN code causes Devel::Trepan to run so slowly that I've not had the patience to wait until it is done. I've tried without the BEGIN, and overwriting caller() still works.

      More serious is the fact that my replaced version of caller() needs to call the original caller (after it strips off the call stack entries on top that are inside the debugger). I tried for bar():

          sub bar {
              local *orig_caller = *CORE::GLOBAL::caller;
              local *CORE::GLOBAL::caller = sub { orig_caller($_[0]+1)} # simplified somewhat
      But I'm getting:
        Deep recursion on anonymous subroutine at .. 
      because I guess that glob assignment has the same address.


        Would it work to just call CORE::caller() from your override?