Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Tk module subs executes without invocation

by dannoura (Pilgrim)
on Aug 29, 2005 at 15:13 UTC ( #487434=perlquestion: print w/replies, xml ) Need Help??
dannoura has asked for the wisdom of the Perl Monks concerning the following question:

I have a module which builds all of the GUI for a script I have. My problem is that when I run the script some of the subs which are bound to events are run without being invoked. For example, the sub _save_defaults, is run. This didn't happen when the subs were in the script (before I put them in a separate module, that is). What am I doing wrong?

Relevant parts of the code are below.

# This is the script my $gui=FP_GUI->new(); # Create main window $gui->menubar(); # Create menu bar MainLoop(); ########## # And this is the module sub new { # Create main window my $class=shift; my $mw=MainWindow->new(-title => 'Get Patents'); $mw->minsize(qw(500 300)); $mw->configure(-bg=>'ivory'); $mw->fontCreate('lbl', -family=>'arial', -size=>'10', -weight=>'bold' ); my $self={mw=>$mw, # Main window status=>'Ready', # Status of program search_entry=>'', # Pointer to search entry field pat_or_sub=>'Both - Pending and Issued', # search for pa +tents or submissions or both strict=>0, # Search based on exact string match class_search=>0, # Include class in results pat=>'All are retrieved regardless of year', # Search ba +sed on specific years, or all years years=>'', # Pointer to years to search field percent_done=>0 # Percent done in progress bar }; return bless $self, $class; } sub menubar { # Create menubar my $self=shift; my $mw=$self->{mw}; my $menubar = $mw->Menu(-menuitems => &_menubar_menuitems($self) ) +; $mw->configure(-menu => $menubar); $mw->bind( "<Control-q>" => \&_quit); $mw->bind( "<Control-s>" => \&_save_defaults($self)); $mw->bind( "<Control-h>" => \&_show_help); } sub _quit { exit 0; } sub _save_defaults { # Save all search parameters my $self=shift; open FH, ">pto search defaults.txt" or die($!); my $search_terms=$self->{search_entry}->get; print FH "Terms\t$search_terms\n"; print FH "Get\t$self->{pat_or_sub}\n"; print FH "Strict\t$self->{strict}\n"; print FH "Class\t$self->{class_search}\n"; print FH "Search by\t$self->{pat}\n"; my $year_string=$self->{years}->get; print FH "Years\t"; print FH "$year_string\n" if ($year_string); close FH; $self->{status}="Search values saved"; } sub _show_help { system('help.html'); } sub _menubar_menuitems { # Menubar items my $self=shift; return [ map ['cascade', $_->[0], -tearoff=> 0, -menuitems => $_->[1]], ['~File', &_file_menuitems($self)], ['~Help', &_help_menuitems()], ]; } sub _file_menuitems { # File menu items my $self=shift; return [ [("command", "~Save Search Parameters", "-accelerator", "Ctrl-s" +), -command=>[\&_save_defaults($self)]], '', [qw/command ~Quit -accelerator Ctrl-q/, -command=>[\&_quit]], ]; } sub _help_menuitems { # Help menu items return [ ['command', 'Help', -command => [\&_show_help]] ]; }

Replies are listed 'Best First'.
Re: Tk module subs executes without invocation
by Tanktalus (Canon) on Aug 29, 2005 at 15:23 UTC

    I've never had any success in pre-binding a variable like this. Try:

    -command=>[ sub { $self->_save_defaults() } ]],

      Magic. Thanks! That works. Can you explain why?

      Also, another question: now that I ported all the subs from the script into a module the script reports:

      Assuming require 'Tk::BrowseEntry' at line 151; Assuming require 'Tk::ProgressBar' at line 169;
      Also something which it hasn't done before (this is despite a use Tk; statement at the beginning of the module and script). Why is that?

        You can only take a reference to a subroutine of some sort in perl5 (perl6 will have more sophisticated binding to allow you to pre-populate certain parameters and pass that code ref around instead of the original routine). So here what I'm doing is creating an anonymous sub that is also a closure - it's closed on $self, retaining the current value of $self at the time of this routine. It then calls the routine we want with the parameters we want - even though the Tk code can't know what $self is to pass it in.

        As to your assuming lines - I'm not sure, I'm not a Tk user. ;-)

Re: Tk module subs executes without invocation
by polettix (Vicar) on Aug 29, 2005 at 17:35 UTC
    (Thanks to Tanktalus for pointing out the relevant line of code :)
    means that you're calling _save_defaults passing $self, taking a reference to the result and putting it inside the anonimous array. This is why you're seeing the unexpected call. You'd better:
    -command=>[\&_save_defaults, $self]
    or follow Tanktalus' suggestion (without the square brackets, you don't need if you pass the sub reference alone).

    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://487434]
Approved by Tanktalus
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2018-02-21 13:04 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (279 votes). Check out past polls.