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

Hi all. I'm stumped. I've been toying with a small financial application using Perl/Tk and I've come across what I think is a scope problem, but it sure doesn't make sense to me. I'm attempting to call a subroutine from a button and pass the value that is supposed to be set from a radiobutton. Like this:
-command => [\&Account_Setup, $acct]
$acct gets set with a radio button variable:
$f->Radiobutton(-text => "Investment", -value => "investment", -variable => \$acct)->pack(-side => 'top', -anchor => 'w');
The subroutine contains a simple print statement for testing:
sub Account_Setup{ my ($acct_type) = shift; print "Account Type: $acct_type\n"; }
The problem is, the button code above doesn't seem to be passing the value stored in $acct. However, this code on the button works:
-command => sub{ print "Account: $acct\n"; }
In addition, if I set the value of $acct right before passing it, the subroutine seems to work fine as well. Is this some sort of scope problem or am I missing something really obvious? Any suggestions would be greatly appreciated. TIA.

Replies are listed 'Best First'.
Re: Scope with Perl/Tk
by pjf (Curate) on Oct 12, 2001 at 07:05 UTC
    G'day berniep,

    When you create your button with:

    -command => [\&Account_Setup, $acct]
    It uses the value of $acct that exists at the time the button is created. If that value of $acct is then changed later on, the button isn't going to pick up on this.

    Instead of passing in $acct (which gives you the contents of the $acct variable), you can instead pass in a reference to the variable:

    -command => [\&Account_Setup, \$acct]
    Now, when your button is pressed, it gets a reference to $acct, which you can dereference to get the current value of $acct, like this:
    sub Account_Setup { my $acct_type = ${shift()}; print "Account Type: $acct_type\n"; }
    This should hopefully solve your problem.

    Trap for the unwary:It's important to use ${shift()} rather than ${shift}. The first is calling perl's built-in shift function and then de-referencing the result into a scalar. The second is the varaible named $shift.

    Cheers,
    Paul

      That worked like a charm. Thanks a bunch!