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

Is it possible for an anonymous subroutine to discover its own code ref?
print sub{ }
gives the code ref of that anonymous sub, but from the main program. Can this be written as
sub {print ...} -> ();
for instance? I'm well aware that this is a silly thing to want to do, but I'm curious.

Replies are listed 'Best First'.
Re: Reference to an anon sub from within. (do my...)
by tye (Sage) on Mar 08, 2005 at 22:55 UTC

    Replace "sub {" with "do { my $sub; $sub = sub {" and add a "}" on the end. Then inside of the sub, $sub will be a reference to the sub:

    do { my $sub; $sub = sub { print "I am $sub\n"; } }->();

    - tye        

Re: Reference to an anon sub from within.
by BrowserUk (Patriarch) on Mar 08, 2005 at 23:12 UTC

    Your not the only one who has wondered :)


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
      Ah ha! Looks like Devel::Caller is the solution. There really should be a perl interface to perl internals built into perl. XS is too scary for me.

        The toughest part of XS is finding information. Much of it is there, but the lack of indexing makes it hard to find, and the lack of simple examples mean that even when you see what you need to know, you don't recognise as such when you start.

        Funnily enough, another interesting reference particularly applicable to your question turned up on the p5p list just a while ago.

        This news://nntp.perl.org/perl.perl5.porters/98762 doesn't work as a link here, but within that post there is a link to PerlAssembly which I haven't had chance to digest yet, but seems to offer some valuable insights into the internals.


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.
Re: Reference to an anon sub from within.
by Sandy (Curate) on Mar 08, 2005 at 22:39 UTC
    Probably not what you are looking for... but...
    my $sub; $sub = sub{print"hello\n";return $sub}; $sub->(); print "$sub\n"; $sub->()->();
    Can't see any use to this.

    UPDATE

    More fun... but still can't imagine why?

    # --- Make a lexical block { my $sub; $sub = sub {sub hello {print"hello\n";return $sub}}; $sub->(); print "$sub\n"; } my $x = &hello; print "address of hello is <$x>\n"; &hello()->();
      The use is that it allows a recursive anonymous subroutine.

      The cost is that the subroutine will now hold a reference to itself and will therefore never get garbage collected.

        Thanks Tilly,

        Here is my recursive 'sort-of' anonymous routine that calculates factors

        # --- Factoring with a nony mouse sub { my $sub; my $fact; $fact = 1; $sub = sub {my $num=shift; $fact=$num*$fact; if ($num==1){print "$fact\n"} else{$num--;$sub->($num)}; return $sub}; $sub->(5); }
        although, by using $sub it's not really anonymous, is it?

        UPDATE

        Improved version of above

        # --- Factoring with a nony mouse sub my $sub; { my $fact; $fact = 1; $sub = sub {my $num=shift; $fact=$num*$fact; $num--; $sub->($num) unless $num==1; return $fact}; } print $sub->(5),"\n";
Re: Reference to an anon sub from within.
by tilly (Archbishop) on Mar 08, 2005 at 22:59 UTC
    I believe that this is only possible if you either set up the binding in advance, or if you use XS to poke around in Perl's internals. If you wanted to use XS, though, you could easily create a function that acts a lot like caller except that it is more informative.

    If you want somewhere to start on trying to write that, you could take a look at the implementation of Want.

      Alternatively, for an example of code that does bind in advance but is thus pure Perl, see Class::Rebless.
Re: Reference to an anon sub from within.
by thor (Priest) on Mar 08, 2005 at 22:36 UTC
    The whole point of a subroutine is to have reusable code or to break something into logical steps. If you're not storing the reference anywhere, what you have isn't a subroutine, it's just code. So, instead of using an anonymous sub, you could write it like so:
    { #your code goes here }
    The braces give everything it's own lexical scope, just like a subroutine has.

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

      Yes, indeed. *sigh*, you people, TOO helpful. I ask a silly question and you assume I am deluded, and not simply wishing to find a silly answer.
Re: Reference to an anon sub from within.
by Roy Johnson (Monsignor) on Mar 08, 2005 at 23:35 UTC
    In your first example, the sub presumably returns something printable. In the second, the print is inside the sub. The two examples behave the same. Yes, you can dereference the sub in the same line you declare it.

    Caution: Contents may have been coded under pressure.
Re: Reference to an anon sub from within.
by blazar (Canon) on Mar 09, 2005 at 10:21 UTC