Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中对另一个模块中的函数进行引用_Perl_Reference_Perl Module_Tk - Fatal编程技术网

在Perl中对另一个模块中的函数进行引用

在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(

我想用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(
        -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是乏味和不必要的。