Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Perl/Tk command execution weirdness

by Guildenstern (Deacon)
on Dec 11, 2000 at 22:48 UTC ( [id://46112]=perlquestion: print w/replies, xml ) Need Help??

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

I have an app written in Perl/Tk. I am having a very strange problem in relation to the Button and Entry widgets. On one dialog I have an Entry widget and a Button. When the Button is pressed, I want to call a sub with the current contents of the Entry widget. Here is the code that attempts to do this:
my $newBtn = $upper->Button('-text' => "New Subdirectory", '-command' => [\&newDir, $direntry->get()]) ->grid('-column' => 1,'-row' => 1);

This code successfully calls the newDir sub, but no value gets passed in. This led me to think that the get() wasn't returning anything so I tried this line instead:
my $newBtn = $upper->Button('-text' => "New Subdirectory", '-command' => sub { print $direntry->get(),"\n"; }) ->grid('-column' => 1,'-row' => 1);

Making this substitution prints out the correct information when the button is clicked.

Why can I only access the contents of the Entry through the anonymous sub? Why does it not seem to pass the value to the newDir sub? Is there some kind of scoping or execution order problem that I'm not aware of here? I'm sure I could wrap the call to newDir in an anonymous sub in the command handler, but the thought of doing that makes me cringe.

Guildenstern
Negaterd character class uber alles!

Replies are listed 'Best First'.
Re: Perl/Tk command execution weirdness
by autark (Friar) on Dec 11, 2000 at 23:00 UTC
    The reason is actually quite obvious once you see why. When you use an anonymous array to create the callback for your button, you create it once and only once. That means that the array will contain f.exs: [CODE(0x80e4ec), ''] The empty string ('') probably would be the output of $directory->get() at the start of the program, so that is what you send to the function.

    Now, when you use an anonymous function, and within it use the code to fetch the output from the Entry widget, it will be called every time. Thus - $directory->get() will be called each time you press the button. This is in contast to the anonymous array, where the get() function only will be called once - when you create the array.

    Autark.

(tye)Re: Perl/Tk command execution weirdness
by tye (Sage) on Apr 17, 2001 at 22:20 UTC

    autark is correct. So I'd write this as:

    my $newBtn= $upper->Button( '-text' => "New Subdirectory", '-command' => sub { newDir( $direntry->get() ) }, )->grid( '-column' => 1, '-row' => 1 );
    (someone asked me about that).

    Also note that current versions of Perl don't ever free anonymous subroutines (because of a reference loop in how they are tracked) so if you replace that button or its action, you now leak memory. (I have a neat Tk app that leaks memory like fishnet because I'm constantly replacing buttons/actions as the state of things change.)

            - tye (but my friends call me "Tye")

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://46112]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2024-04-19 16:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found