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

Hi Monks,

Is there a way of finding out how deep the stack is so I can loop through them and show the entire call stack?

perlfunc tells me:

($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require) = caller($i);
but no hint if $i can be read from somewhere... I assume not otherwise it would say.

Also the fact that: "Be aware that the optimizer might have optimized call frames away before caller()" may make this an impossible ask anyhow.

___ /\__\ "What is the world coming to?" \/__/ www.wolispace.com

Replies are listed 'Best First'.
Re: caller counter
by blokhead (Monsignor) on Dec 04, 2003 at 01:15 UTC
    You may find Getting size of call stack relevant. Basically, the argument to caller is how many frames down on the stack to return. You'll need to start at 0 and increment the argument until you exceed the current stack depth, at which point caller will return undef in scalar context. There's no simple way (that I know of) to just get the depth explicitly.

    blokhead

      Thanks,

      Just what I needed to know!

      ___ /\__\ "What is the world coming to?" \/__/ www.wolispace.com
Re: caller counter
by mpeppler (Vicar) on Dec 04, 2003 at 01:17 UTC
    Check out Carp::Heavy's longmess_heavy() subroutine to see how it is done. If you want to show the call stack you may be better off using one of the Carp subs rather than rolling your own...

    Michael

Re: caller counter
by !1 (Hermit) on Dec 04, 2003 at 01:19 UTC

    I'm short on time but I know this question has been asked before. The sub looked something like:

    sub stack_depth() { my $depth = 1; $depth++ while defined caller($depth); --$depth; }

    I think that's right.

      If you start with my $depth = 0;, there's no need for the final -- $depth.

      Abigail

        Sorry to disagree, but that would only be if the contents of stack_depth were used as a snippet in place of the subroutine.

        I know you know this, but for those who don't:

        sub stack_depth() { my $depth = 1; $depth++ while defined caller($depth); --$depth; }

        This subroutine is meant to be used as in the following snippet:

        #!/usr/bin/perl -wl use strict; sub stack_depth() { my $depth = 1; $depth++ while defined caller($depth); --$depth; } sub test1 { print stack_depth;test2() } # should be 1 sub test2 { print stack_depth;test3() } # should be 2 sub test3 { print stack_depth } # should be 3 print stack_depth; # what's our stack depth here? should be 0 test1(); __END__ outputs: 0 1 2 3

        The reason that $depth is set to 1 instead of to 0 in the subroutine is because we're interested in the depth of the stack from wherever the subroutine was called. Since stack_depth itself is a subroutine, we already know that it will have been placed on the stack. Thus we know caller(0) will be defined. When the loop completes, $depth will contain the depth of our subroutine regardless of whether we set $depth = 0 or $depth = 1. Thus the reason for --$depth as the implicit return.

Re: caller counter
by hardburn (Abbot) on Dec 04, 2003 at 14:45 UTC

    Other Monks have noted that this is possible with caller alone, but you might also want to check Devel::StackTrace. This will also allow you to see what arguments were passed (which you can pass to Data::Dumper for printing).

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated