在Perl中对另一个模块中的函数进行引用
我想用Perl中的Tk制作一个小型GUI,它有两个按钮:Race和Quit 我希望Race按钮运行一个位于模块在Perl中对另一个模块中的函数进行引用,perl,reference,perl-module,tk,Perl,Reference,Perl Module,Tk,我想用Perl中的Tk制作一个小型GUI,它有两个按钮: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(
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(),
时,它不起作用
我理解这是因为我没有传递函数的引用。如何传递对位于另一个命名空间(模块)中的函数的引用?此语法很简单:
$mw->Button(
-text => 'Race',
-command => \&Car::Race,
)->pack;
但是,如果需要将任何特殊参数传递给该函数或将其作为方法调用,则仍然需要anon sub:
$mw->Button(
-text => 'Race',
-command => sub { Car->Race(@_) },
)->pack;
这个函数调用Race作为打包Car的方法,并将所有参数传递给它
Car->Race()
和……一样吗
Car->can('Race')->('Car');
^^^^^^^^^^^^^^^^ ^^^^^
sub ref args
如您所见,一个参数被传递给sub。如果您不想使用anon sub,您必须指示Tk传递该参数。Tk确实有办法做到这一点
-command => [ Car->can('Race'), 'Car' ],
这可能会快一点,也可能不会快一点,但它肯定没有那么清楚
-command => sub { Car->Race() },
至于其他包中的子程序?如果你有一种叫做使用的东西
Car::Race();
-command => \&Car::Race,
这将被称为使用
Car::Race();
-command => \&Car::Race,
但这不是你在这里拥有的
*-使用自动加载的模块除外。这就是为什么自动加载器应该覆盖
can
\&Car::Race
不等同于sub{Car->Race()}
,模块通常使用use
加载,而不是require
。我已经加载了整个汽车
模块,使用'use'Car'@ikegami,我提到了call as function和call as method,这取决于您需要调用什么。require和use是不同的,但use实际上只是BEGIN{require Foo;Foo->import()代码>就像perldoc说的@Illya Melamed,是的,是我的错。修正了,谢天谢地将其缩放为一个闭包不是很准确,因为它不会关闭任何东西。我会解决的。最后,你需要一个anon sub或闭包是不正确的。Tk确实提供了一种指定要传递给回调的参数的方法。请尝试-command=>sub{goto Car->Race();},
有关详细信息,请参见perldoc-f goto
。@shawnhcorey=>它将尝试转到与Car->Race()的字符串化返回值同名的标签。对goto
的正确用法是类似于sub{@}'Car';goto&{Car->can('Race')}
。但在这种情况下,使用goto是乏味和不必要的。