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

O enlightened masters of the Perl core:

This is a deep one. I'm trying to understand the $hasargs element of the return from caller (when called in a list context). The man page contains this tantalizing nugget:

 $hasargs is true if a new instance of @_ was set up for the frame.

Which almost tells me something ... but then again not quite. Google searches have likewise proved fruitless.

The reason I'm hot on the trail of $hasargs is that it seems linked to this code from Carp.pm:

if ( $call_info{has_args} ) { my @args; if ( @DB::args == 1 && ref $DB::args[0] eq ref \$i && $DB::args[0] == \$i ) { @DB::args = (); # Don't let anyone see the address of $ +i local $@; my $where = eval { my $func = $cgc or return ''; my $gv = B::svref_2object($func)->GV; my $package = $gv->STASH->NAME; my $subname = $gv->NAME; return unless defined $package && defined $subname; # returning CORE::GLOBAL::caller isn't useful for trac +ing the cause: return if $package eq 'CORE::GLOBAL' && $subname eq 'c +aller'; " in &${package}::$subname"; } // ''; @args = "** Incomplete caller override detected$where; \@DB: +:args were not set **"; } else { @args = map { Carp::format_arg($_) } @DB::args; } if ( $MaxArgNums and @args > $MaxArgNums ) { # More than we want to show? $#args = $MaxArgNums; push @args, '...'; } # Push the args onto the subroutine $sub_name .= '(' . join( ', ', @args ) . ')'; }

See that message in the middle there? about "incomplete caller override"? I keep seeing that when I try to look at my code in the debugger. And I deeply suspect it's coming from (indirectly) Hook::LexWrap, where the Damian is indeed overriding caller. I'm not sure why Carp think it's being overridden incompletely, but it obviously has something to do with $hasargs, and I feel like if I could just understand WTF that is, I'd understand WTF is going on in the code.

Thanks to anyone who has the insight into perlguts to help me out.

Replies are listed 'Best First'.
Re: Trying to understand (caller($i))[4], a.k.a. $hasargs
by ikegami (Patriarch) on Feb 13, 2012 at 10:12 UTC

    It indicates a lack of &f.

    >perl -E"sub g { say +(caller 0)[4]?'':'no ', 'new @_; ', 0+@_, ' args +: ', @_ } sub f { g(@_) } f('abc');" new @_; 1 args: abc >perl -E"sub g { say +(caller 0)[4]?'':'no ', 'new @_; ', 0+@_, ' args +: ', @_ } sub f { &g } f('abc');" no new @_; 1 args: abc
      It indicates a lack of &f.

      Excellent. That makes sense now; thanks for the concise explanation.

      Now, what about the Carp code? The OP code is drawn from 5.14.2, but I have the same issues in 5.12.4, and the Carp code is a bit simpler there:

Re: Trying to understand (caller($i))[4], a.k.a. $hasargs [solution]
by ikegami (Patriarch) on Feb 14, 2012 at 06:47 UTC

    I believe the problem can be solved by changing

    my @caller = CORE::caller($i++) or return;
    to
    my @caller = CORE::caller() eq 'DB' ? do { package DB; CORE::caller($i++) } : CORE::caller($i++) or return;

      Excellent! Yes, that stops the error entirely. I'll submit it to DC as a patch. Thanks for the code.

Re: Trying to understand (caller($i))[4], a.k.a. $hasargs [diagnostic]
by ikegami (Patriarch) on Feb 14, 2012 at 06:36 UTC

    it obviously has something to do with $hasarg

    No, it has to do with @DB::args.

    I'm not sure why Carp think it's being overridden incompletely

    It seems to indicate @DB::args needs to be adjusted somehow to compensate for the fact that caller isn't being called from where the user thinks it is being called.

    [Update: The check was introduced by this commit. Read the commit message for some info. ]

    The OP code is drawn from 5.14.2, but I have the same issues in 5.12.4, and the Carp code is a bit simpler there:

    That's because code was added to 5.14 to identify where the bad code is located ($where).

      Read the commit message for some info.

      Okay, read that, and it helped, but I can't say that I understood it all. DB is the debugger package, right? So I guess CORE::caller is setting up ... something ... that helps the debugger do ... something ... and folks who override CORE::GLOBAL::caller have to do the same thing or chaos will ensue? Am I getting that right? :-)

      That's because code was added to 5.14 to identify where the bad code is located ($where).

      Yeah, I saw that, but, in my case, $where was blank anyway, so I didn't see any point in including that code in retrospect. ;->