Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

CORE::GLOBAL::caller reports strange lines around coderef definitions

by ed_hoch (Sexton)
on Jan 25, 2016 at 19:45 UTC ( [id://1153603]=perlquestion: print w/replies, xml ) Need Help??

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

perl caller seems to be giving the "wrong" line around definition of coderef. I'd expect caller to flag line 8, but it's flagging line 12. The deparser seems to give some quirky output, too. Can anyone help me figure out what's going on here? Thanks
> perl -v | head -n2 This is perl 5, version 16, subversion 2 (v5.16.2) built for x86_64-li +nux > cat -n program.pl 1 sub foo { 2 print join(", ", caller(0)) . "\n"; 3 } 4 5 my %hash = ( 6 A => 'foo', 7 B => { 8 C => foo(), 9 }, 10 D => 'foo', 11 E => sub { return 1; }, 12 F => 'foo', 13 G => 'foo', 14 ); 15 16 my $foo = 'bar'; > perl program.pl main, program.pl, 12, main::foo, 1, 1, , , 0, , > perl -MO=Deparse,-p,-l program.pl #line 3 "program.pl" sub foo { #line 2 "program.pl" print((join(', ', caller(0)) . "\n")); } #line 12 "program.pl" (my(%hash) = ('A', 'foo', 'B', {'C', foo()}, 'D', 'foo', 'E', sub { #line 11 "program.pl" (return 1); } , 'F', 'foo', 'G', 'foo')); #line 16 "program.pl" (my $foo = 'bar'); program.pl syntax OK
  • Comment on CORE::GLOBAL::caller reports strange lines around coderef definitions
  • Download Code

Replies are listed 'Best First'.
Re: CORE::GLOBAL::caller reports strange lines around coderef definitions
by stevieb (Canon) on Jan 25, 2016 at 20:20 UTC

    Interesting. I can't say why this happens, but if you pre-build the cref before you insert it into the hash, caller() will report the first line of the href as the actual caller (line 4):

    sub foo { print caller(0); } my $cref = sub { return 1; }; my $h = { a => 1, b => foo(), d => 'foo', c => $cref, m => 'bar', };

    Perhaps upon building the hash, the anonymous sub has to be seen/compiled before foo() actually gets called (which is why caller states the line immediately after)? perlsub says that anonysubs are compiled at runtime, so this actually makes sense.

    Update:Note that the following works exactly as you'd expect. perl has to delve into the hash far enough to compile the anonymous sub, and that's it. If there isn't any runtime compiling to do in the hash, the caller will actually appear as the first line of the hash definition:

    sub foo { print caller(0); } my $h = { a => 1, c => sub { return 1; }, b => foo(), d => 'foo', m => 'bar', };
Re: CORE::GLOBAL::caller reports strange lines around coderef definitions
by ikegami (Patriarch) on Jan 26, 2016 at 14:07 UTC

    At run-time, only the line numbers of statements are available (for efficiency reasons), so it should say the caller is line 5.

    $ perl -e' # 1 my %h = ( # 2 a => 1, # 3 b => warn("This is line 4"), # 4 c => 1 # 5 ); # 6 ' # 7 This is line 4 at -e line 2.

    That it says the statement starts a line 12 is a bug. As you probably noticed, the problem is related to the nested statement at line 11. Replace the sub { } with a constant and the caller will become line 5.

    $ perl -MO=Concise,-exec -e' my %h = ( a => 1, b => 1, c => 1, ); my $x = 1; ' 1 <0> enter 2 <;> nextstate(main 1 -e:2) v:{ <-- Sets the line number to 2. 3 <0> pushmark s 4 <$> const[PV "a"] s/BARE 5 <$> const[IV 1] s 6 <$> const[PV "b"] s/BARE 7 <$> const[IV 1] s 8 <$> const[PV "c"] s/BARE 9 <$> const[IV 1] s a <0> pushmark s b <0> padhv[%h:1,3] lRM*/LVINTRO c <2> aassign[t2] vKS d <;> nextstate(main 2 -e:7) v:{ <-- Sets the line number to 7. e <$> const[IV 1] s f <0> padsv[$x:2,3] sRM*/LVINTRO g <2> sassign vKS/2 h <@> leave[1 ref] vKP/REFC -e syntax OK $ perl -MO=Concise,-exec -e' my %h = ( a => 1, b => sub { }, c => 1, ); my $x = 1; ' 1 <0> enter 2 <;> nextstate(main 2 -e:5) v:{ <-- Sets the line number to 5!?!? 3 <0> pushmark s 4 <$> const[PV "a"] s/BARE 5 <$> const[IV 1] s 6 <$> const[PV "b"] s/BARE 7 <0> pushmark sRM 8 <$> anoncode[CV ] lRM 9 <1> refgen lK/1 a <$> const[PV "c"] s/BARE b <$> const[IV 1] s c <0> pushmark s d <0> padhv[%h:2,4] lRM*/LVINTRO e <2> aassign[t3] vKS f <;> nextstate(main 3 -e:7) v:{ <-- Sets the line number to 7. g <$> const[IV 1] s h <0> padsv[$x:3,4] sRM*/LVINTRO i <2> sassign vKS/2 j <@> leave[1 ref] vKP/REFC -e syntax OK

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-19 21:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found