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

Track the filename/line number of an anonymous coderef

by merlyn (Sage)
on Dec 10, 2004 at 00:21 UTC ( [id://413725]=CUFP: print w/replies, xml ) Need Help??

Use the imported "Sub" instead of "sub", and you can create an anonymous coderef that acts normally except when dereferenced as a string, where it returns the filename and line number of where it was defined. See the example for usage.

This code came from the discussion in the thread that includes •Re^5: How to de-reference a coderef?.

BEGIN { package MagicalCoderef; use overload '""' => sub { require B; my $ref = shift; my $gv = B::svref_2object($ref)->GV; sprintf "%s:%d", $gv->FILE, $gv->LINE; }; sub main::Sub (&) { return bless shift, __PACKAGE__; } } my $s = Sub { print +shift }; $s->("hello world\n"); print "$s\n";

Replies are listed 'Best First'.
Re: Track the filename/line number of an anonymous coderef
by brian_d_foy (Abbot) on Dec 11, 2004 at 06:23 UTC

    I changed this around to do it for arbitrary coderefs, since I get to deal with some that come from other sources. Instead of catching them at definition time, I "enchant" them later.

    This looks like it could be a useful decorator if I work on the concept a little more. So Randal, who wants to upload it to CPAN first?

    #!/usr/bin/perl my $a = sub { print "I am A\n" }; my $b = sub { print "I am B\n" }; $a->(); $b->(); $c = MagicalCodeRef->enchant( $a ); $a->(); print STDERR "That was $a I just called\n"; BEGIN { package MagicalCodeRef; use overload '""' => sub { require B; my $ref = shift; my $gv = B::svref_2object($ref)->GV; sprintf "%s:%d", $gv->FILE, $gv->LINE; }; sub enchant { bless $_[1], $_[0] } }
    --
    brian d foy <bdfoy@cpan.org>
      A warning to anybody who finds this from google.

      This approach worked perfectly in perl 5.8.8 and perl 5.20.2, but as of perl 5.30.3, this no longer works.
      At that version, "$gv->LINE" outputs some huge number instead of a LINE number.

      Somehow using "x $sub" in the debugger still gets the correct answer, so I think there must be some solution.

        This approach worked perfectly in perl 5.8.8 and perl 5.20.2, but as of perl 5.30.3, this no longer works. At that version, "$gv->LINE" outputs some huge number instead of a LINE number.

        I can't reproduce the problem you report: it works fine for me at 5.30.0, 5.32.0 and 5.34.0 (which I happen to have installed), and I just built 5.30.3 and it works fine for me on that too.

        Could you provide perl -V output? Perhaps there's something specific to your build.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://413725]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (1)
As of 2024-04-19 00:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found