http://www.perlmonks.org?node_id=1199342
jh has asked for the wisdom of the Perl Monks concerning the following question:

Using 5.18, I have found that in a multi-line function call, where one of the arguments contains a dereference operation, that caller() returns the line where the dereference occurs, not the line where the function call actually happens. On a multi-line function call with no dereference operation, caller() seems to work:

Here is a minimal example that demonstrates this behavior:

#!/usr/bin/perl -w use strict; sub print_calling_line { my $actual_line = $_[0]; my $caller_line = (caller)[2]; printf "Called from line %2d; caller() reports line %2d\n", $actual_line, $caller_line; } print_calling_line( __LINE__, { A => 1, B => 2, C => 3 } ); print_calling_line( __LINE__, %{{ A => 1, B => 2, C => 3 }} );

This outputs

Called from line 11; caller() reports line 11 Called from line 15; caller() reports line 16

I am guessing this is related to CORE::GLOBAL::caller reports strange lines around coderef definitions, though it's not the same exactly.

Indexing into a reference does not seem to be a problem, just a dereference of the whole data structure (including getting a slice). Here is a more elaborate example that demonstrates this behavior:

#!/usr/bin/perl -w use strict; my %HASH = ( A => 1, B => 2, C => 3, D => 4, E => 5 ); my $HASHREF = \%HASH; my @ARRAY = ( 1 .. 5 ); my $ARRAYREF = \@ARRAY; my $SCALAR = "strings_are_scalar"; my $SCALARREF = \$SCALAR; sub CODE { rand } my $CODEREF = \&CODE; sub print_calling_line { my $actual_line = shift; my $caller_line = (caller)[2]; my $different = $actual_line != $caller_line ? "***" : ""; printf "%3s Called from line %2d; caller() reports line %2d [args: @ +_]\n", $different, $actual_line, $caller_line; } print "\n"; print_calling_line( __LINE__, %HASH ); print_calling_line( __LINE__, $HASHREF ); print_calling_line( __LINE__, %{$HASHREF} ); print_calling_line( __LINE__, $HASH{A} ); print_calling_line( __LINE__, $HASHREF->{A} ); print_calling_line( __LINE__, @HASH{qw(B C D)} ); print_calling_line( __LINE__, @{$HASHREF}{qw(B C D)} ); print "\n"; print_calling_line( __LINE__, %HASH ); print_calling_line( __LINE__, $HASHREF ); print_calling_line( __LINE__, %{$HASHREF} ); print_calling_line( __LINE__, $HASH{A} ); print_calling_line( __LINE__, $HASHREF->{A} ); print_calling_line( __LINE__, @HASH{qw(A)} ); print_calling_line( __LINE__, @{$HASHREF}{qw(A)} ); print "\n"; print_calling_line( __LINE__, @ARRAY ); print_calling_line( __LINE__, $ARRAYREF ); print_calling_line( __LINE__, @{$ARRAYREF} ); print_calling_line( __LINE__, $ARRAY[0] ); print_calling_line( __LINE__, $ARRAYREF->[0] ); print_calling_line( __LINE__, @ARRAY[2 .. 4] ); print_calling_line( __LINE__, @{$ARRAYREF}[2 .. 4] ); print "\n"; print_calling_line( __LINE__, @ARRAY ); print_calling_line( __LINE__, $ARRAYREF ); print_calling_line( __LINE__, @{$ARRAYREF} ); print_calling_line( __LINE__, $ARRAY[0] ); print_calling_line( __LINE__, $ARRAYREF->[0] ); print_calling_line( __LINE__, @ARRAY[2 .. 4] ); print_calling_line( __LINE__, @{$ARRAYREF}[2 .. 4] ); print "\n"; print_calling_line( __LINE__, $SCALAR ); print_calling_line( __LINE__, $SCALARREF ); print_calling_line( __LINE__, ${$SCALARREF} ); print "\n"; print_calling_line( __LINE__, $SCALAR ); print_calling_line( __LINE__, $SCALARREF ); print_calling_line( __LINE__, ${$SCALARREF} ); print "\n"; print_calling_line( __LINE__, &CODE ); print_calling_line( __LINE__, $CODEREF ); print_calling_line( __LINE__, &{$CODEREF} ); print "\n"; print_calling_line( __LINE__, &CODE ); print_calling_line( __LINE__, $CODEREF ); print_calling_line( __LINE__, &{$CODEREF} ); print "\n"; print_calling_line( __LINE__, ${$SCALARREF} ); print_calling_line( __LINE__, ${$SCALARREF} ); print_calling_line( __LINE__, "space_1", ${$SCALARREF} ); print_calling_line( __LINE__, "space_1", "space_2", ${$SCALARREF} ); print_calling_line( __LINE__, "space_1", "space_2", ${$SCALARREF}, "space_3", "space_4", ); print "\n";

outputs:

Called from line 22; caller() reports line 22 [args: A 1 D 4 C 3 E + 5 B 2] Called from line 23; caller() reports line 23 [args: HASH(0x974070 +)] Called from line 24; caller() reports line 24 [args: A 1 D 4 C 3 E + 5 B 2] Called from line 25; caller() reports line 25 [args: 1] Called from line 26; caller() reports line 26 [args: 1] Called from line 27; caller() reports line 27 [args: 2 3 4] Called from line 28; caller() reports line 28 [args: 2 3 4] Called from line 31; caller() reports line 31 [args: A 1 D 4 C 3 E + 5 B 2] Called from line 34; caller() reports line 34 [args: HASH(0x974070 +)] *** Called from line 37; caller() reports line 38 [args: A 1 D 4 C 3 E + 5 B 2] Called from line 40; caller() reports line 40 [args: 1] Called from line 43; caller() reports line 43 [args: 1] Called from line 46; caller() reports line 46 [args: 1] *** Called from line 49; caller() reports line 50 [args: 1] Called from line 54; caller() reports line 54 [args: 1 2 3 4 5] Called from line 55; caller() reports line 55 [args: ARRAY(0x99973 +0)] Called from line 56; caller() reports line 56 [args: 1 2 3 4 5] Called from line 57; caller() reports line 57 [args: 1] Called from line 58; caller() reports line 58 [args: 1] Called from line 59; caller() reports line 59 [args: 3 4 5] Called from line 60; caller() reports line 60 [args: 3 4 5] Called from line 63; caller() reports line 63 [args: 1 2 3 4 5] Called from line 66; caller() reports line 66 [args: ARRAY(0x99973 +0)] *** Called from line 69; caller() reports line 70 [args: 1 2 3 4 5] Called from line 72; caller() reports line 72 [args: 1] Called from line 75; caller() reports line 75 [args: 1] Called from line 78; caller() reports line 78 [args: 3 4 5] *** Called from line 81; caller() reports line 82 [args: 3 4 5] Called from line 86; caller() reports line 86 [args: strings_are_s +calar] Called from line 87; caller() reports line 87 [args: SCALAR(0x9999 +e0)] Called from line 88; caller() reports line 88 [args: strings_are_s +calar] Called from line 91; caller() reports line 91 [args: strings_are_s +calar] Called from line 94; caller() reports line 94 [args: SCALAR(0x9999 +e0)] *** Called from line 97; caller() reports line 98 [args: strings_are_s +calar] Called from line 102; caller() reports line 102 [args: 0.728356104 +883463] Called from line 103; caller() reports line 103 [args: CODE(0x999a +50)] Called from line 104; caller() reports line 104 [args: 0.996905960 +000248] Called from line 107; caller() reports line 107 [args: 0.690901509 +291631] Called from line 110; caller() reports line 110 [args: CODE(0x999a +50)] *** Called from line 113; caller() reports line 114 [args: 0.898765947 +759735] Called from line 118; caller() reports line 118 [args: strings_are +_scalar] *** Called from line 119; caller() reports line 120 [args: strings_are +_scalar] *** Called from line 122; caller() reports line 124 [args: space_1 str +ings_are_scalar] *** Called from line 126; caller() reports line 129 [args: space_1 spa +ce_2 strings_are_scalar] *** Called from line 131; caller() reports line 134 [args: space_1 spa +ce_2 strings_are_scalar space_3 space_4]