Sometimes a subroutine needs to have some way to refer to itself (usually for recursion). For named subs, it's simple - just use the name, exactly like you would do in C or in other languages:

sub recurse { my $level = shift; print "recurse [$level]\n"; recurse($level - 1) if $level > 0; }

However, there are ways to subvert this type of reference. Consider the following code:

#!/usr/bin/perl -w use strict; local $\ = "\n"; sub oldsub { my $level = shift; print "oldsub [$level]"; oldsub($level - 1) if $level > 0; } sub newsub { print "newsub [$_[0]]"; } my $oldsub_ref = \&oldsub; $oldsub_ref->(2); print '-' x 10; *oldsub = \&newsub; $oldsub_ref->(2);

with the output:

oldsub [2] oldsub [1] oldsub [0] ---------- Subroutine main::oldsub redefined at ./typeglob_clobber.pl line 22. oldsub [2] newsub [1]

This is, I must admit, an unlikely situation (and it's caught by warnings). Clobbering the typeglob of a named sub, while holding a reference to the original crosses the borderline of sanity IMHO (in for-production code at least). But you never know... Careless use of run-time compilation constructs like do or eval comes to mind. Anyway, advocating against recursion-by-name is not the point of my post.

For an anonymous sub, a safe way to hold a reference to itself is to embed it inside an outer closure:

my $coderef = do { my $selfref; $selfref = sub { # use $selfref here for recursion }; };

This way, the sub can use the cloistered $selfref confidently, because no outer code can clobber it (well, unless the sub leaks out references to it, of course).

Of course it's possible to use this method in order to "bulletproof" named subs too, if you're really paranoid. A named sub defined this way won't suffer from the problems present in the first code snippet:

{ my $selfref; sub named { # use $selfref here } $selfref = \&named; }

All this is OK and fine with me, but I still wonder - is there a generic, built-in way to get the reference to the currently running subroutine? Someting in the caller spirit? I was surprised to find out that caller offers pretty much everything in terms of introspection, except for code references. Maybe I'm overlooking something?


In reply to sub getting reference to itself : generic way by calin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.