2010-04-12 29 views
2

我发现有点奇怪,我必须在为Tkx小部件指定-command参数时匿名封装定义的子例程。我是否总是必须提供Tkx的-command参数为匿名子例程?

摘录从TkDocs tutorial说明了这一点:

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

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

当我写-command => &calculate()-command => \&calculate()为什么它不工作?

回答

6

您没有语法完全正确。您的示例调用子例程(&绕过任何原型),并将返回值(&calculate())或对其的引用(\&calculate())传递给-command选项。你想给子程序本身分配一个参考,你可以通过这个参考:

-command => \&calculate 

请注意缺少尾括号。还要注意,你不能以这种方式传递参数。如果你想这样做,你需要或者包裹调用一个匿名的子程序:

-command => sub { calculate(12) } 

或传递选项数组引用,而不是代码的参考:

-command => [\&calculate, 12] 

有之间的微妙差别这两种形式在使用变量而不是字面值时非常重要。

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

当调用该命令时,将使用第一个窗体更改为$x。在第二种形式下,他们不会;每个调用将在创建绑定时看到该值。这两种形式都很有用。在决定使用哪一种时,你只需要做出正确的判断。

+0

我开悟了。但我仍然不明白为什么'\&calculate'语法不适用于我... – Zaid 2010-04-12 17:06:50

+0

@Zaid:我运行示例代码将'sub {calculate()}'更改为'\&calculate',它的工作原理是预期。说它“不起作用”是绝望的模糊。当你尝试时发生了什么? – 2010-06-03 19:30:03

+0

'\'计算'本身就是一种享受。 arrayref是什么让我绊倒,但你的解释清除了为什么。谢谢一堆......如果可以的话,我会两次投票赞成! – Zaid 2010-06-04 07:17:35

2

它应该与-command => \&calculate一起使用。请注意缺少括号。

你给出的例子实际上是执行子程序,并将它返回的值赋给-command键。

欲了解更多信息请参阅perlsubperlref

+0

没有。它不执行,有或没有parens。 – Zaid 2010-04-12 08:10:04

+0

看到' \%calculate'工作时没有括号,如果我需要传递参数呢? – Zaid 2010-04-12 08:25:31

+0

这应该是'\&计算',而不是'\%计算'... – Zaid 2010-04-12 09:22:53

2

扎伊德说,“我很开明,但我仍然 不明白为什么\ &计算 语法不和我一起工作... - 扎伊德 24分钟前”

Zaid,\ &计算语法确实有效。您正在尝试使用\(计算)(\)语法。第一个绑定到“子程序计算稍后运行的引用”,后者绑定为“引用(不带参数的计算的返回值计算,并绕过参数原型)。

你有没有一个较长的,可编译的代码片段,我们可以用于测试/分析?我最近不熟悉TK.

+0

TkDocs网站上的代码。按照原始文章中的链接,将匿名子例程更改为'\&calculate',并让我知道它是否适合您。它不适合我。 – Zaid 2010-04-12 18:13:33

相关问题