дать ссылку на функцию в другом модуле в Perl - PullRequest
2 голосов
/ 06 сентября 2011

Я хочу создать небольшой графический интерфейс с использованием Tk в Perl, который будет иметь 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(),, это не сработало.

Я понимаю, что это потому, что я не передаю ссылку на функцию. Как передать ссылку на функцию, которая находится в другом пространстве имен (модуле)?

Ответы [ 2 ]

7 голосов
/ 06 сентября 2011
Car->Race()

- это то же самое, что и

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

. Как видите, аргумент передается в подпрограмму.Если вы не хотите использовать anon sub, вам придется проинструктировать Tk передать этот аргумент.У Tk есть способ сделать это.

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

Это может быть или не быть немного быстрее, но это определенно не так ясно, как

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

Что касается подпрограмм в других пакетах?Если у вас есть что-то, что вызывается с помощью

Car::Race();

, это будет вызываться с использованием

-command => \&Car::Race,

Но это не то, что у вас есть здесь.

* - за исключением модулей, использующихAUTOLOAD.Вот почему автозагрузчики должны переопределять can.

3 голосов
/ 06 сентября 2011

Этот синтаксис прост:

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

Но если вам нужно передать какие-либо специальные аргументы этим функциям или вызвать его как метод, вам все равно понадобится подпрограмма anon:

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

Этот метод вызывает Race как метод пакета Car и передает ему все аргументы.

...