Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Getting file and line number where a subroutine is declared

by Ovid (Cardinal)
on Feb 02, 2009 at 16:08 UTC ( #740731=perlquestion: print w/ replies, xml ) Need Help??
Ovid has asked for the wisdom of the Perl Monks concerning the following question:

Given a subroutine reference, is there a way to find out the file and line number where the subroutine was declared? warn and friends seems to get this right, but I need this externally. Here's my test program:

#!/usr/bin/perl -l use strict; use warnings; use B; # line 99 'bin/some_code.pl' { no strict 'refs'; print B::svref_2object(\*{'Foo::some_sub'})->LINE; print B::svref_2object(\&Foo::some_sub)->GV->LINE; } Foo::some_sub(); package Foo; # line 23 'bin/some_file.pl' sub some_sub { warn "Got to here"; }

That outputs:

102 102 Got to here at 'bin/some_file.pl' line 24.

The line information is not what I'm expecting, so I assume I'm doing something wrong (B::GV has a corresponding FILE method, but until I get LINE working, it's not much use to me).

Comment on Getting file and line number where a subroutine is declared
Select or Download Code
Re: Getting file and line number where a subroutine is declared
by ikegami (Pope) on Feb 02, 2009 at 16:25 UTC

    In case it helps, warn gets its info from the most recently executed nextstate op.

    $ perl -e' if ($false) { # This is line 2 } elsif (warn) { # This is line 4 } ' Warning: something's wrong at -e line 2. $ perl -MO=Concise -e' if ($false) { # This is line 2 } elsif (warn) { # This is line 4 } ' 6 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 4 -e:2) v ->3 - <1> null vKP/1 ->6 4 <|> cond_expr(other->5) vK/1 ->7 - <1> ex-rv2sv sK/1 ->4 3 <#> gvsv[*false] s ->4 - <@> scope vK ->- 5 <0> stub v ->6 - <1> null vK/1 ->- 9 <|> and(other->a) vK/1 ->6 8 <@> warn[t2] sK ->9 7 <0> pushmark s ->8 - <@> scope vK ->- a <0> stub v ->6 -e syntax OK
Re: Getting file and line number where a subroutine is declared
by kyle (Abbot) on Feb 02, 2009 at 16:40 UTC

    It works better if it's rearranged.

    use B; $\="\n"; package Foo; # line 23 'bin/some_file.pl' sub some_sub { warn "Got to here"; } # line 99 'bin/some_code.pl' print "some_sub: ",B::svref_2object(\&Foo::some_sub)->GV->LINE; { no strict 'refs'; print "some_other_sub: ",B::svref_2object(\*{'Foo::some_other_sub' +})->LINE; } Foo::some_sub(); __END__ some_sub: 25 some_other_sub: 102 Got to here at 'bin/some_file.pl' line 24.

    This code is a little over my head to be honest, but my guess is that your references to Foo::some_sub in the no strict 'refs' block are creating the darned thing right there on the spot. Perhaps another monk can explain this behavior.

    I don't know if this is helpful or not, but I found it interesting.

      Perhaps another monk can explain this behavior.

      \&Foo::some_sub autovivifies a sub stub at run-time (just like sub Foo::some_sub; would at compile-time).

      $ perl -le' print(exists(&Foo::some_sub)?1:0, defined(&Foo::some_sub)?1:0); $x=\&Foo::some_sub; print(exists(&Foo::some_sub)?1:0, defined(&Foo::some_sub)?1:0); eval "sub Foo::some_sub { print \"foo\" }"; print(exists(&Foo::some_sub)?1:0, defined(&Foo::some_sub)?1:0); $x->(); ' 00 10 11 foo

      As demonstrated, this permits the reference to be taken to a sub that has yet to be defined.

      \&Foo::some_sub creates glob entry at compile-time.

      $ perl -le' print(exists($Foo::{not_a_sub})?1:0); print(exists($Foo::{some_sub})?1:0); $x=\&Foo::some_sub; ' 0 1

        \&Foo::some_sub autovivifies a sub stub at run-time (just like sub Foo::some_sub; would at compile-time).

        So it will work fine as long as we don't make any reference to the sub in any compiled code that comes before the definition.

        use B; $\="\n"; # line 99 'bin/some_code.pl' { no strict 'refs'; print B::svref_2object(eval q(\\*{'Foo::some_sub'}))->LINE; print B::svref_2object(eval q(\\&Foo::some_sub))->GV->LINE; } eval q{Foo::some_sub()}; package Foo; # line 23 'bin/some_file.pl' sub some_sub { warn "Got to here"; } __END__ 25 25 Got to here at 'bin/some_file.pl' line 24.

        Of course, string eval has a code smell, but so does no strict 'refs'.

Re: Getting file and line number where a subroutine is declared
by brian_d_foy (Abbot) on Feb 02, 2009 at 16:41 UTC

      The problem with those, I think, is the problem I had above. They won't work if the code is declared after I try to inspect it because GV->LINE apparently reports the first glob entry ... and that's created when I take the reference.

      On P5P, Rafael suggested I use START->line instead. It returns the line number of the first expression encountered in the sub. Not perfect, but close enough to what I want (I also encountered GV->LINE returning the line number of the closing curly brace in the sub. Much worse than START.

        They won't work if the code is declared after I try to inspect it

        You seem to be confusing function declaration and function definition. You are getting is the line number of the declaration. What you want to line number of the definition.

Re: Getting file and line number where a subroutine is declared
by LanX (Canon) on Mar 22, 2014 at 20:05 UTC
    Did anyone find a solution now? :)

    Though otherwise documented does B::svref_2object($coderef)->GV->LINE; only return the LAST line of the subs-body.

    And B::svref_2object($coderef)->START->line; only returns the first OP of the body╣, i.e. not only the function head is missing, but also any empty or commented lines at body's start.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    ╣)to be precise only the line of the END of a multiline OP.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://740731]
Approved by kyle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (12)
As of 2014-12-18 06:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (42 votes), past polls