给出对 Perl 中另一个模块中函数的引用

发布于 2024-12-03 08:03:40 字数 784 浏览 1 评论 0原文

我想在 Perl 中使用 Tk 制作一个小型 GUI,它有 2 个按钮:RaceQuit

我希望 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(), 它不起作用。

我知道这是因为我没有传递对该函数的引用。如何传递对位于另一个命名空间(模块)中的函数的引用?

I want to make a small GUI using Tk in Perl that will have 2 buttons: Race and Quit.

I want the Race button to run a function that is located in a module Car and is called Race.

I've written the following code:

#!/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;

It works, but It seems stupid to me to make an unnamed subroutine that will just call another subroutine. But when I tried to use -command => sub Car->Race(), or -command => sub \&Car->Race(), it didn't work.

I understand that this is because I'm not passing a reference to the function. How do I pass a reference to a function that is located in another namespace (module)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北方的巷 2024-12-10 08:03:40
Car->Race()

与您所看到的相同*

Car->can('Race')->('Car');
^^^^^^^^^^^^^^^^   ^^^^^
sub ref            args

,参数被传递给 sub。如果您不想使用 anon sub,则必须指示 Tk 传递该参数。 Tk 确实有办法做到这一点。

-command => [ Car->can('Race'), 'Car' ],

这可能会快一点,也可能不会快一点,但它绝对不如

-command => sub { Car->Race() },

其他包中的子例程那么清晰?如果你有一个叫做 using 的东西,

Car::Race();

它就会被称为 using

-command => \&Car::Race,

但这不是你这里所拥有的。

* — 使用 AUTOLOAD 的模块除外。这就是自动加载器应该覆盖 can 的原因。

Car->Race()

is the same* as

Car->can('Race')->('Car');
^^^^^^^^^^^^^^^^   ^^^^^
sub ref            args

As you can see, an argument is passed to the sub. If you don't want to use an anon sub, you'll have to instruct Tk to pass that argument. Tk does have a means of doing that.

-command => [ Car->can('Race'), 'Car' ],

This may or may not be a little faster, but it's definitely not as clear as

-command => sub { Car->Race() },

As for subroutines in other packages? If you have something that's called using

Car::Race();

it would be called using

-command => \&Car::Race,

But that's not what you have here.

* — Except for modules using AUTOLOAD. This is why autoloaders should override can.

谈情不如逗狗 2024-12-10 08:03:40

这种语法很简单:

$mw->Button(
        -text    => 'Race',
        -command => \&Car::Race,
)->pack;

但是如果您需要将任何特殊参数传递给该函数或将其作为方法调用,您仍然需要一个匿名子:

$mw->Button(
        -text    => 'Race',
        -command => sub { Car->Race(@_) },
)->pack;

这个调用 Race 作为包 Car 的方法并将所有参数传递给它。

This syntax is symple:

$mw->Button(
        -text    => 'Race',
        -command => \&Car::Race,
)->pack;

But if you need to pass any special arguments to that functions or call it as method, you still need an anon sub:

$mw->Button(
        -text    => 'Race',
        -command => sub { Car->Race(@_) },
)->pack;

This one calls Race as method of package Car and pass all arguments to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文