原文:
12. Common Problems.
Everything in Tk-land is a reference. When defining callbacks take care to pass variables by reference. Callbacks are closures and to ensure a variable gets its current value, as opposed to its value when the callback is defined, pass by reference, e.g.: $frog = 123; $b = $mw->Button( -text => 'Push Me', -command => [ sub { my($widget, $frog) = @ARG; print STDERR "widget=$widget!\n"; print STDERR "frog=$$frog!\n"; }, $mw, \$frog, ], ); # end Button definition
If $frog is not passed by reference the print statement will always output "123" (actually, the print as it exists will print nothing since it's trying to dereference $frog, which presumably is now not a reference). Note that by definition all perl/Tk widgets are already references, since they're simply Perl objects, and that's why you do not have to print $$widget!
A good "reference" for handling references and dereferencing are the perlref(1) and perlobj(1) man pages. A good "reference" for the various data types you will encounter in this kind of perl programming is Tom Christiansen's Perl Data Structures Cookbook which is now available as the perldsc(1) man page.
Also beware the traps that befall perl4 programmers in making the move to perl 5. References for this include the new perltrap(1) man page as well as William Middleton's perl425 trap document at: http://www.perl.com/perl/all_about/perl425.htmlor http://www.perltk.org/contrib/misc/perl425.html
译文:
12. 基本问题
Tk范围内的所有组件都是引用(reference)。在定义回应函数的时候要注意通过引用来传递变量。因为回应函数是关闭的,所以要想保证一个传人的变量得到的是它的当前值,而不是在回应函数定义时的值,就必须通过引用来传递。例如:
$frog = 123;
$b = $mw->Button(
-text => 'Push Me',
-command => [
sub {
my($widget, $frog) = @ARG;
print STDERR "widget=$widget!\n";
print STDERR "frog=$$frog!\n";
}, $mw, \$frog,
],
); # end Button definition
这里,如果$frog不是通过引用传递的,那么print语句会总是输出”123”(实际上,这个print语句不会输出任何信息,因为它总是试图解开$ frog的引用,而其实它根本不是……)。注意,所有的Perl/Tk组件在定义的时候就已经是引用了,因为它们也都只是Perl的对象,这也就是为什么我们不需要print $$widget的原因。
要掌握引用和解引用的最后的参考资料就是perlref和perlobj的手册页。而对于我们将在这一类型的Perl编程中会遇到的各种各样的数据类型,Tom Christiansen的《Perl Data Structures Cookbook》将是很好的参考资料,而且它现在已经在perldsc的手册页中了!
同时也要注意在perl4到perl5过程中编程上可能出现的陷阱。关于这个问题的参考资料包括新的perltrap手册页和William Middleton的关于perl425陷阱的文档:
http://www.perl.com/perl/all_about/perl425.html
或
http://www.perltk.org/contrib/misc/perl425.html