Один из вариантов - использовать анонимную подпрограмму:
package Resources;
my $my_class = new MY_CLASS;
our $resource = { '/list' => sub { $my_class->list_files(@_); } };
...
package main;
# dereference the code ref
&{$Resources::resource->{'/list'}};
# or call it:
$Resources::resource->{'/list'}();
Если вы измените ссылки $my_class
, они также будут изменены в анонимной функции. Это может быть то, что вы хотите; если нет, продолжайте чтение для функции (bindMethod
), которая связывает объект и метод.
Если вы не хотите, чтобы анонимная функция появлялась в стеке:
our $resource = { '/list' => sub { unshift @_, $my_class;
goto &MyClass::list_files; } };
Обратите внимание, что эта форма goto
не является обычной инструкцией goto - это хвостовой вызов .
Вы могли бы определить вспомогательный метод для настройки привязки, хотя, честно говоря, он мало что дает.
sub bindMethod {
my ($obj, $meth) = @_;
return sub { unshift @_, $obj; goto &{$meth}; }
}
my $my_class = new MyClass;
our $resource = { '/list' => bindMethod($my_class, \&MyClass::list_files) };
Вот версия bindMethod
, которая не требует указания класса с именем метода.
sub bindMethod {
my ($obj, $meth) = @_;
if (! ref $meth) {
my $class = ref $obj;
$meth = \&{"${class}::$meth"};
}
return sub { unshift @_, $obj; goto &{$meth}; }
}
...
my $my_class = new MyClass;
our $resource = { '/list' => bindMethod($my_class, 'list_files') };