in reply to Re^3: Identify the package a subroutine is being called from
in thread Identify the package a subroutine is being called from

Did you try it? This is the trick Devel::StackTrace uses.

  • Comment on Re^4: Identify the package a subroutine is being called from

Replies are listed 'Best First'.
Re^5: Identify the package a subroutine is being called from
by jettero (Monsignor) on Jun 07, 2008 at 04:00 UTC
    Why yes, in fact I did try it. I got undef every time, for many variations of your code... It seems you're 100% right, but I couldn't get it to work without copying D::ST directly like this:
    sub calling_object { my @a = do { package DB; @DB::args = (); caller(2); }; $DB::args[0]; }

    It definitely doesn't work for me the way you had it.

    Oh, I got it. After much fiddling, it's the scalar context. The trick does not work when you $foo=caller(2); Must be ($foo) = caller(2); or caller() doesn't populate args. I can't tell if you changed it to @foo or if I transcribed it wrong, but my original cut and paste had $foo = caller(2).

    Also, in my previous post, I had assumed $DB::args was pure black magic. I had no idea it was documented grey magic.

    -Paul

      I pulled it right out of SUPER, which is why it had list context correct but was missing the package declaration, as I never thought to put it in a block. Clever trick.

        I just spent most of my freetime for the day flipping through cop.h, op.c, pp_ctl.c, and for some reason, perly.y.

        It would appear that blk_sub structs store arguments and CODE refs but never the caller object. So, although you can tease it out of the arguments that happen to be sitting in the stack, you can't really protect against (or even detect) something like unshift @_, "haha, fooled you" in the object that would be returned by calling_object() ... even using XS. I was hoping I could come up with something better in XS, but I couldn't find a way.

        That's too bad, but it's not the end of the world I suppose. It's an anticlimactic end to my day of hacking though.

        It's interesting that shift while @_; doesn't ruin the @_ stored in the stack, but unshifting onto it does. Weird, splice @_, 0, 300 doesn't ruin it either, but @_ = () does. I can't explain that.

        -Paul