Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

caller() mystery

by rovf (Priest)
on Sep 26, 2008 at 09:37 UTC ( [id://713834]=perlquestion: print w/replies, xml ) Need Help??

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

It seems that I haven't understood properly the perldocs of the caller function. My understanding was that with caller(1), I walk up one frame (i.e. get the information about who is calling me), with caller(2) I walk up 2 frames, etc.

But now look at the following example program. _format_caller is called twice; the first time it is supposed to print what is returned by caller(1), the second time caller(2).

use strict; use warnings; sub _format_caller { my @x=caller($_[0]); print "elements:",scalar(@x),"\n"; print(join(',',@x),"\n"); } sub f { my $level=$_[0]; print "test caller $level\n"; _format_caller($level); } f(1); f(2);
The actual printout looks like this:
> Use of uninitialized value in join or string at U:\develsv\ARTS\playgr +ound\callertest.pl line 7. Use of uninitialized value in join or string at U:\develsv\ARTS\playgr +ound\callertest.pl line 7. Use of uninitialized value in join or string at U:\develsv\ARTS\playgr +ound\callertest.pl line 7. test caller 1 elements:10 main,U:\develsv\ARTS\playground\callertest.pl,16,main::f,1,,,,2,UUUUUU +UUUUU test caller 2 elements:0
Well, the uninitialized warnings are because some of the elements returned by caller are undef. But why don't I get anything back in the case of caller(2)?

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: caller() mystery
by ikegami (Patriarch) on Sep 26, 2008 at 09:47 UTC
    There's only two levels of caller in this case. Do you expect it to return the name of your shell?
    use strict; use warnings; sub _format_caller { my @x=caller($_[0]); print(join(',',@x[0..2]),"\n"); } sub f { my $level=$_[0]; print "test caller $level\n"; _format_caller($level); print("\n"); } f($_) for 0..2;
    test caller 0 main,713838.pl,12 test caller 1 main,713838.pl,16 test caller 2 Use of uninitialized value in join or string at 713838.pl line 6. Use of uninitialized value in join or string at 713838.pl line 6. Use of uninitialized value in join or string at 713838.pl line 6. ,,
      There's only two levels of caller in this case.

      Hmmm.... I was counting 3:

      • Level 0: _format_caller
      • Level 1: main::f
      • Level 2: The main program itself

      It seems that the top-level program is not represented by a stack frame...
      -- 
      Ronald Fischer <ynnor@mm.st>

        caller(0) returns info about _format_caller's caller.
        caller(1) returns info about f's caller
        caller(2) would return info about the main program's caller, but that's no longer in Perl. What are you expecting it to return?

Re: caller() mystery
by andreas1234567 (Vicar) on Sep 26, 2008 at 10:17 UTC
    $ perl use strict; use warnings; use Log::Log4perl qw(:easy); Log::Log4perl->easy_init($DEBUG); sub show_call_stack { my $max_depth = 7; my $i = 1; # start on 1 to skip last function call DEBUG("--- Begin stack trace ---"); while ((my @call_details = (caller($i++))) && ($i < $max_depth)) { DEBUG( "$call_details[1] line $call_details[2] in function $call_detail +s[3]"); } DEBUG("--- End stack trace ---"); } sub foo { show_call_stack(); bar(); } sub bar { show_call_stack(); tze(); } sub tze { show_call_stack(); } # ------ main ------ foo(); __END__ 2008/09/26 12:16:35 --- Begin stack trace --- 2008/09/26 12:16:35 - line 33 in function main::foo 2008/09/26 12:16:35 --- End stack trace --- 2008/09/26 12:16:35 --- Begin stack trace --- 2008/09/26 12:16:35 - line 20 in function main::bar 2008/09/26 12:16:35 - line 33 in function main::foo 2008/09/26 12:16:35 --- End stack trace --- 2008/09/26 12:16:35 --- Begin stack trace --- 2008/09/26 12:16:35 - line 25 in function main::tze 2008/09/26 12:16:35 - line 20 in function main::bar 2008/09/26 12:16:35 - line 33 in function main::foo 2008/09/26 12:16:35 --- End stack trace --- $
    --
    No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]

      I finally understand! (caller(0))[1,2] give me filename and line of the place where I was called from; but to see from what other subroutine I was called, I need to access (caller(1))[3]. Thanks a lot for clarification!

      -- 
      Ronald Fischer <ynnor@mm.st>
Re: caller() mystery
by JavaFan (Canon) on Sep 26, 2008 at 09:52 UTC
    Because counting frames is 0-indexed. You do not have a third frame, so caller(2) won't return anything.

    Try calling f(0) and f(1).

Log In?
Username:
Password:

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

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

    No recent polls found