Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: How to de-reference a coderef?

by mpeters (Chaplain)
on Dec 09, 2004 at 14:58 UTC ( #413559=note: print w/replies, xml ) Need Help??

in reply to How to de-reference a coderef?

Dereferencing and getting the name of the referenced object are two different things. If I had a reference to an array there is no way to find out what the name of that array is so why would there be a way to do it with subroutines/coderefs?

Replies are listed 'Best First'.
Re^2: How to de-reference a coderef?
by gellyfish (Monsignor) on Dec 09, 2004 at 15:16 UTC

    Oh there *is* a way, but it's not big and it's not clever and won't work with anonymous subs, but you can do it if you really, really, really must:

    + sub foo { } + my $bar = \&foo; + foreach my $foo ( keys %:: ) { my $zub = \&{$::{$foo}}; if ( $bar eq $zub ) { print $foo,"\n"; last; } }
    See I told you it wasn't big or clever ....


      What about other namespaces? What about multiple matches? A sub is a little like an inode on a unix filesystem: it may have several names, or none; and several handles, or none.

        ... and probably XS defined subroutines and AUTOLOADed methods and so and so forth. If I had listed all the caveats it would have taken up more space than the code ;-) This was posted not so much as a solution to the OPs question, rather as a riposte to the bald statement that it couldn't be done.


      It may not be big but it certainly is clever!

      To those kind people who pointed out that:
      (a)I could execute the sub without knowing its name - I knew that
      (b)That it might not have a name - in my case I knew it had a name but not what the name was.

      My problem was that the coderef was being passed in from somewhere else but I needed to get at the subroutine name, not to execute it but to print for debug, logging, etc.

      As usual, perlmonks has excelled itself for speed and quality of response ...


        I can tell you're already happy with the solution you've got, but I'd like to recommend a few alternates anyway. :-)

        I think you're losing a lot of flexibility by requiring the passed in coderef to be a named sub in the same namespace. Any time you're passing around coderefs, anonymous subs become more and more useful. To this end, I can think of a few ways to allow them:

        • Pass in a label along with the coderef. This would allow the caller to use anonymous coderefs as well as refs to named subs, and would avoid the "in another namespace" problem.
        • Pass in a label, but only optionally. If there is no label, the symbol table is searched. If there is one, it's used instead.
        • Pass in an object. At first this sounds a bit ugly, but it could be something as simple as:
          foobar(Code::Wrapper->new( code => \&foo )); foobar(Code::Wrapper->new( code => sub { "baz" }, label => "baz" ) +)

          Then this object could encapsulate the behavior mentioned earlier, by either searching the symbol table or using the specified label.

        Which one you choose depends on how much flexibility you want in the future, and how much you want to insulate certain parts of your code from others. I have a feeling you will just go with the symbol table scan, but hopefully you'll at least give my ideas some consideration.

        Would caller help? It's used to examine the call stack. For example, the Carp module (included with perl) uses it to warn/die with stack traces or from the perspecive of the caller.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://413559]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2018-01-19 23:46 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (226 votes). Check out past polls.