in reply to Good way of getting subroutine name from ref?

Trickery.

use B; sub cv2name { # Updated to use scalar eval { ... } to trap errors and still use +the proper context return scalar eval { my $obj = B::svref_2object( shift ); my $package = $obj->STASH->NAME; '&' . ( $package eq 'main' ? '' : "${package}::" ) . $obj->GV- +>NAME; } }

Replies are listed 'Best First'.
Re: Re: Good way of getting subroutine name from ref?
by ysth (Canon) on Dec 07, 2003 at 01:58 UTC
    When using B this way, I like to guard against bad input. For instance, if you pass an array ref, with the above you'll croak with: Can't locate object method "STASH" via package "B::AV". Rather than check with ref or reftype or can or check what type of object svref_2object returns, I just wrap it in an eval and return undef if something goes wrong:
    use B; sub cv2name { eval { my $obj = B::svref_2object( shift() ); $obj->STASH->NAME . "::" . $obj->GV->NAME; } || undef; }
      Oh that's a good point. I like it. One clarification though - eval returns undef when it fails so your `|| undef` is pure obfuscation. You disguise that eval already has the || undef behaviour automatically.
        I know eval is documented that way, but it actually returns an empty list in list context, which messes things up if you are passing cv2name as a parameter to another function with other parameters following.