Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

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: (8)
As of 2017-05-24 11:51 GMT
Find Nodes?
    Voting Booth?