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

Running Perl/Tk under Windows/XP. Tried to bind a key to a subroutine call with an argument, but it didn't work. Here is stripped-down code:

use Tk; sub print_args { $ix = 0; foreach $arg (@_) { print "ARG $ix = $arg \n"; $ix++; } print "------------------\n"; } $mw = MainWindow -> new (); $mw -> title ("Test bind with parms"); $fill = $mw -> Label (-text => "TEST BIND - try both button and dow +n arrow") -> pack (); $quit_but = $mw -> Button (-text => "QUIT", -background => "#ffffcc", -borderwidth => 5, -relief => ridge, -command => sub{exit}) -> pack (-side => bottom, -fill => "x"); $test_but = $mw -> Button (-text => "Invoke via button", -background => "#ddffff", -borderwidth => 5, -relief => ridge, -command => [ \&print_args, 3, 2, 11 ] ) -> pack (-side => bottom, -fill => "x"); $mw -> bind ('<Key-Down>' => [ \&print_args, 3, 2, 11 ]); MainLoop;
When I press the button, I get this (as expected):
ARG 0 = 3 ARG 1 = 2 ARG 2 = 11 ------------------
But when I press the down arrow:
ARG 0 = MainWindow=HASH(0x2c5c1cc) ARG 1 = 3 ARG 2 = 2 ARG 3 = 11
Oops? Known bug??

Replies are listed 'Best First'.
Re: Bind mishandles arguments
by Marshall (Canon) on May 31, 2011 at 08:53 UTC
    The code appears to be working just fine. The text of Mastering Perl Tk is online - look at Chapter 15. Read about the "The Event Structure" and "the event object". Tk is giving you as the first arg (0), the event object in your bind of the down arrow case. You can throw away this object reference if you want, but this event object can tell you a lot about the context of how this key got pressed. Maybe it does something different depending upon which Window has focus. The args provided by the -command in the Button object are different as you have noted. But of course in this case, you know exactly what got pushed in what window since you made the button.

    Read chapter 15 and see if that helps.

      OK, many thanks -- let's just say it's somewhat surprising (to me) that "\&cmd, arg" produces different results in these two contexts, given that the purpose is so similar.
Re: Bind mishandles arguments
by choroba (Cardinal) on May 31, 2011 at 10:43 UTC
    If you want the same behaviour, you can call
    $mw->bind('<Key-Down>' => sub { $test_but->invoke } );
    instead.
      Thank you!