开发者

Do I always have to provide Tkx's -command argument an anonymous subroutine?

I find it a bit weird that I have to wrap defined subroutines anonymously when specifying the -command argument for Tkx widgets.

An excerpt from a TkDoc开发者_StackOverflows tutorial demonstrates this:

my $cb = $frm->new_ttk__button ( -text => "Calculate",
                                 -command => sub {calculate();}  );

sub calculate {
   $meters = int(0.3048*$feet*10000.0+.5)/10000.0 || '';
}

Why doesn't it work when I write -command => &calculate() or -command => \&calculate()?


You don't have the syntax quite right. Your examples call the subroutine (the & bypasses any prototypes) and passes either the return value (&calculate()) or a reference to it (\&calculate()) to the -command option. You want to assign a reference to the subroutine itself, which you can do via:

-command => \&calculate

Note the lack of trailing parentheses. Also note that you can't pass arguments this way. If you want to do that you need to either wrap the call in an anonymous subroutine:

-command => sub { calculate(12) }

or pass the option an ARRAY reference instead of a CODE reference:

-command => [\&calculate, 12]

There's a subtle difference between the two forms that's important if you use a variable instead of a literal value.

-command => sub { calculate($x) }  # creates a closure over $x
-command => [\&calculate, $x]      # makes a copy of $x

Using the first form changes to $x will be visible when the command is invoked. Under the second form they won't be; each invocation will see the value at the moment the binding was created. Both forms are useful; you just need to exercise good judgment when deciding which to use.


It should work with -command => \&calculate. Note the lack of parentheses.

The examples you gave are actually executing the subroutine and assigning the value returned by it to the -command key.

For more info see perlsub and perlref


Zaid said, "I'm enlightened. But I still don't see why the \&calculate syntax doesn't work with me... – Zaid 24 mins ago"

Zaid, the \&calculate syntax does work. You were trying to use the \&calculate() syntax. The first binds to "a reference to the subroutine calculate to be run later", the latter binds as "a reference to (the return value of a call calculate with no arguments, and bypassing argument prototypes ).

Do you have a longer, compilable code snippet that we can use for testing/analysis? I am not recently familiar with TK.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜