Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Getting file and line number where a subroutine is declared

by kyle (Abbot)
on Feb 02, 2009 at 16:40 UTC ( #740739=note: print w/ replies, xml ) Need Help??


in reply to Getting file and line number where a subroutine is declared

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.


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

    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'.

        Symbolic refs will do instead of eval.

        { no strict 'refs'; my $name = 'Foo::some_sub'; print B::svref_2object(\*$name)->LINE; print B::svref_2object(\&$name)->GV->LINE; $name->(); }

        It can be done with strict refs too.

        my $glob = $::{'Foo::'}{some_sub}; print B::svref_2object(\*$glob)->LINE; print B::svref_2object(\&$glob)->GV->LINE; $glob->();

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (7)
As of 2015-07-04 01:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (57 votes), past polls