contact@solamen.fr has asked for the wisdom of the Perl Monks concerning the following question:

Hi

The following code leads to a strange behavior.

First pressing "Calculate" button prints the expected result: Uw=2.6.

Then if I press "Characteristics" button and close the Characteristics window, pressing again "Calculate" button leads to Uw=0 for the same values of independent variables! I tend to conclude that $window{xAf} is somehow considered as a character...

Could somebody please tell me what I am doing wrong?

use strict; use warnings; use Tk; my $roomTl; my %window = (xAf=>0.20); my $mw = new MainWindow( ); $mw->Button( -text => "\n Characteristics \n", -command => \&roomSub, )->pack(-fill => "x"); $mw->Button( -text => "\n Calculate \n", -background => "red", -command => \&designSub, )->pack(-fill => "x"); MainLoop; sub roomSub { if (! Exists ($roomTl)) { $roomTl = $mw->Toplevel( ); $roomTl->Entry( -textvariable => \$window{xAf}, )->pack(-fill => 'x'); } else { $roomTl->deiconify(); $roomTl->raise(); } } sub designSub { my $Uf = 13; my $Uw = $window{xAf} * $Uf; print "Uf = $Uf \t xAf = $window{xAf} \t Uw = $Uw \n"; }

Replies are listed 'Best First'.
Re: perl/Tk Problem with referenced variable in Entry
by choroba (Cardinal) on Nov 05, 2013 at 21:47 UTC
    Weird. You can simplify the code by removing the global $roomTl (which shortens roomSub), and you can also use a plain scalar to the same effect. I also added Devel::Peek to include some internal details.
    #!/usr/bin/perl use warnings; use strict; use Tk; use Devel::Peek; my $val = 0.20; my $mw = 'MainWindow'->new; $mw->Button( -text => "\n Characteristics \n", -command => \&room, )->pack(-fill => "x"); $mw->Button( -text => "\n Calculate \n", -background => "red", -command => \&design, )->pack(-fill => "x"); MainLoop(); sub room { my $roomTl = $mw->Toplevel; $roomTl->Entry( -textvariable => \$val, )->pack(-fill => 'x'); } sub design { my $Uf = 13; my $Uw = $val * $Uf; # HERE print Dump($val), "\t Uf = $Uf \t val = ${\$val} \t Uw = $Uw \n"; }

    Interestingly, to make the behaviour correct, just change the "# HERE" line to

    my $Uw = "$val" * $Uf;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: perl/Tk Problem with referenced variable in Entry (bug)
by Anonymous Monk on Nov 05, 2013 at 23:34 UTC

    Looks like when the toplevel gets destroyed, the window{xAf} gets grinitialigzed to 0 under some circumstances ... probably a bug since as choroba shows stringification gives the correct value

    This might be a bug worth reporting to the maintainer, rt://Tk

     

    However, creating a Dialog instead of a toplevel naturally works as intended

    sub roomSub { if (! Exists ($roomTl)) { warn "textvariable"; #~ $roomTl = $mw->Toplevel(); $roomTl = $mw->Dialog(); $roomTl->Entry( -textvariable => \$window{xAf}, )->pack(-fill => 'x'); } $roomTl->Show(); }

    Also, I won't bug you about tk scoping function argument passing

      Thanks for your answer and for bugging me :) with argument passing and closures: I had no idea it was a lack of robustness in perl (or just Tk?). I have literally hundreds of variables handled in dozens of hashes so I feel kind of reluctant to rewrite my subroutines so they take arguments and return variables. For the moment I turned towards choroba patch and interpolate as much as possible. I also forwarded the post to rt.Tk as you suggested. Best
        rt.cpan 90077
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: perl/Tk Problem with referenced variable in Entry
by eserte (Deacon) on Nov 06, 2013 at 17:15 UTC
    Confirmed problem with Tk 804.031 and perl 5.8 .. 5.16. But it works with perl 5.18 (see RT bug report for more information).