in reply to Re: Odd lexical variable behavior -- why does this happen?
in thread Odd lexical variable behavior -- why does this happen?

Ok, so I did some digging. No MULTICALL. I was off track in my first post.

I confirmed this by adding an extra scope. That would fix the problem I've observed before.
sub count_up { { . . . } }
$cnt=0; $progress=0 $cnt=0; $progress=20 $cnt=0; $progress=40 $cnt=0; $progress=60

Turns out the variable is always different than the one in the previous call to the function. (As it should be since we keep creating external references to it.)

my $r = \$progress; print("address of \$progress=$r\n");
$cnt=0; $progress=0 address of $progress=SCALAR(0x19fc970) $cnt=0; $progress=20 address of $progress=SCALAR(0x19fe710) $cnt=0; $progress=40 address of $progress=SCALAR(0x1cfdb0c) $cnt=0; $progress=60 address of $progress=SCALAR(0x1d13fc4)

That means something is setting the new variable to the value the old one had. It must be configure.

$pb->configure( -from => 0, -to => 20, -variable => \$progress, ## store the reference. ); $progress = 0;
$cnt=0; $progress=0 $cnt=0; $progress=0 $cnt=0; $progress=0 $cnt=0; $progress=0

I confirmed this by looking at the source. Note $$varref = $oldval;.

sub variable { my $c = shift; my $oldvarref = $c->{'-variable'}; my $oldval = $$oldvarref if $oldvarref; if(@_) { my $varref = shift; if ($oldvarref) { $c->traceVdelete($oldvarref); } $c->{'-variable'} = $varref; $c->traceVariable($varref, 'w', sub { $c->value($_[1]) }); $$varref = $oldval; _layoutRequest($c,2); } $oldval; }

Changing the var that holds the progress shouldn't change the value of the progress bar, and there's code to makes sure of that.

Perhaps you want

use strict; use warnings; use Tk; use Tk::ProgressBar; my $mw = MainWindow->new(-title=>"Bug Demo"); my $progress; my $pb = $mw->ProgressBar( -width => 20, -length => 200, -blocks => 20, -from => 0, -to => 20, -variable => \$progress, ## store the reference. )->pack(); my $button = $mw->Button( -text => 'Press this!', -command => \&count_up, )->pack(); MainLoop; sub count_up { $progress = 0; $mw->update; for (1..20) { select(undef, undef, undef, 0.01); $progress++; $mw->update; } }

Replies are listed 'Best First'.
Re^3: Odd lexical variable behavior -- why does this happen?
by radiantmatrix (Parson) on Sep 13, 2007 at 15:36 UTC

    Aha! Thank you!

    The work-around you presented is one approach, my particular answer was to

    $pb->configure( -variable => undef );
    on the way out of scope. Thanks for shedding light on this, I don't know how or why I missed this when I scanned ProgressBar.pm...

    As for "Changing the var that holds the progress shouldn't change the value of the progress bar", I sort of disagree. Since ProgressBar doesn't actually update that variable, I'd expect that changing to a different variable, you'd want to use that variable's value. As the documentation for Tk::ProgressBar says about -variable:

    Specifies the reference to a scalar variable to link to the ProgressBar. Whenever the value of the variable changes, the ProgressBar will upate to reflect this value.

    I'd expect that changing variables entirely would also change "the value of the variable", but obviously others (including the original author) have different expectations.

    Thanks again for the insight. ++!

    <radiant.matrix>
    Ramblings and references
    The Code that can be seen is not the true Code
    I haven't found a problem yet that can't be solved by a well-placed trebuchet