Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Re^4: How to de-reference a coderef?

by revdiablo (Prior)
on Dec 09, 2004 at 17:51 UTC ( #413628=note: print w/replies, xml ) Need Help??

in reply to Re^3: How to de-reference a coderef?
in thread How to de-reference a coderef?

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.

Replies are listed 'Best First'.
•Re^5: How to de-reference a coderef?
by merlyn (Sage) on Dec 09, 2004 at 18:02 UTC
    To make that even simpler, you could write a subroutine called Sub that takes a coderef argument and records its file and line number and returns an object that when used as a coderef invokes the coderef, but when used as a string returns the filename/linenumber of creation. How's that for slick? I may even have to code that up for a snippet. Usage would be something like:
    my $sub = Sub { my $x = shift; print $x }; $sub->("foo"); # prints foo print "that was from $sub\n";
    Pretty simple to do.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

    update: see Track the filename/line number of an anonymous coderef.
      I'd like to see this, namely as in my head I can only imagine the syntax of...

      my $sub = Sub sub { my $x = shift; print $x };

      Being that I thought { } was the anonymous hash composer. I'm really curious about this though, and syntax reduction in general. Writing things that act like Ruby/Groovy blocks is kind of ugly when you have to use the sub keyword all of the time.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://413628]
and cookies bake in the oven...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2018-05-23 17:43 GMT
Find Nodes?
    Voting Booth?