我想在Perl中使用Tk制作一个小GUI,它将有2个按钮:Race和Quit。
我希望Race按钮运行位于模块Car
中的功能,称为Race
。
#!/usr/bin/perl -w
use strict;
use warnings;
use Car;
use Tk;
my $mw = MainWindow->new;
$mw->Label(-text => "The Amazing Race")->pack;
$mw->Button(
-text => 'Race',
-command => sub {Car->Race()},
)->pack;
$mw->Button(
-text => 'Quit',
-command => sub { exit },
)->pack;
MainLoop;
它可以工作,但是对我来说,让一个未命名的子程序只调用另一个子程序似乎很愚蠢。但当我试图使用-command => sub Car->Race(),
或-command => sub &Car->Race(),
时,它不起作用。
我理解这是因为我没有传递对函数的引用。如何传递对位于另一个命名空间(模块)中的函数的引用?
Car->Race()
等于
Car->can('Race')->('Car');
^^^^^^^^^^^^^^^^ ^^^^^
sub ref args
如你所见,一个参数被传递给子对象。如果你不想使用匿名子对象,你必须指示Tk传递该参数。Tk确实有这样做的方法。
-command => [ Car->can('Race'), 'Car' ],
这可能快一点,也可能快一点,但它肯定不如
清晰。-command => sub { Car->Race() },
至于其他包中的子程序呢?如果你有一个叫做using
的东西Car::Race();
将使用
调用-command => &Car::Race,
但你这里没有。
& # 42;本;除了使用AUTOLOAD
的模块。这就是为什么自动加载器应该覆盖can
。
语法很简单:
$mw->Button(
-text => 'Race',
-command => &Car::Race,
)->pack;
但是如果你需要传递任何特殊的参数给那个函数或者作为方法调用它,你仍然需要一个匿名子:
$mw->Button(
-text => 'Race',
-command => sub { Car->Race(@_) },
)->pack;
这个调用Race作为package Car的方法,并将所有参数传递给它。