in reply to Debugger and lexicals

Monks, I appreciate the variety of comments. In response, I made some variants to my test code.

In mytest2.pm, add a second subroutine below the first:

sub mt3 { return $a + 19; }

There's no call to mt3() in the top-level script. Nonetheless, the interpreter doesn't know that (I don't think), and shouldn't make $a disappear. But adding the additional sub definition doesn't change the outcome: the debugger still doesn't see $a inside mt2() (with the commented line in place).

Change #2: our $a; instead of my $a; . Now, the debugger sees $a on the first line of mt2() , whether or not there's a mt3() defined.

Surely it's a matter of $a being a lexical. But the debugger knows about 'global' lexicals if they're used in a function in which the debugger has stopped, and doesn't if they're not used there -- even when the lexicals are available to the whole module (well, from definition to EOF).

I don't know enough about the debugger to know if this is by design, or I haven't set a switch or option, or other operator error. Is this where PadWalker comes in?

-- Lee

Replies are listed 'Best First'.
Re^2: Debugger and lexicals
by dave_the_m (Monsignor) on Aug 08, 2011 at 13:28 UTC
    This has nothing to do with the debugger and everything to do with closures. All the debugger does is do the equivalent of executing an eval at the point of interest in the code. Consider the following:
    { my $a = 1; sub f1 { $a; print "f1: a=", eval('$a'), "\n"; } sub f2 { print "f2: a=", eval('$a'), "\n"; } } f1(); f2();
    when run, this outputs:
    f1: a=1 f2: a=
    (The block is there to mimic the implied block that's wrapped around a use'd file). Here, f1 creates a closure, which means it captures the initial (and in this case, only) instance of $a; i.e. a reference to $a is stored in f1's pad. During execution, when the block end is reached, $a goes out of scope for the main sub, and the reference to it from the main pad is removed. When the evals are run, the eval in f1 sees $a since that sub has captured it; whereas the f2 eval can't see it, as it wasn't captured by f2, and no longer exists in the parent.

    Dave.