Передача объекта функции и вызов его - PullRequest
29 голосов
/ 05 августа 2009

Как передать функцию a в функцию b и получить b вызов a в Perl?

Ответы [ 4 ]

43 голосов
/ 05 августа 2009

Вот полный рабочий скрипт, который демонстрирует, что вы спрашиваете.

sub a { print "Hello World!\n"; }

sub b {
    my $func = $_[0];
    $func->();
}

b(\&a);

Вот объяснение: вы берете ссылку на функцию a, говоря \&a. В этот момент у вас есть ссылка на функцию; в то время как обычно функция вызывается с помощью func(), вы вызываете ссылку на функцию с помощью $func->()

Синтаксис -> относится и к другим ссылкам. Например, вот пример работы с ссылками на массив и хэш:

sub f {
    my ($aref, $href) = @_;
    print "Here's an array reference: $aref->[0]\n";  # prints 5
    print "Here's a hash ref: $href->{hello}\n";      # prints "world"
}

my @a = (5, 6, 7);
my %h = (hello=>"world", goodbye=>"girl");
f(\@a, \%h);
9 голосов
/ 05 августа 2009

Вы не можете передать функцию другой функции напрямую. Вместо этого вы передаете ссылку в функцию. Чтобы вызвать функцию, вы разыменовываете ее (как код CODE), используя ->();

sub a { print @_ }

sub b {
  my $f = shift;  # assuming that $f is a function reference...
  $f->(@_);       # call it with the remaining arguments
}

b(\&a, "hello, world!");  # prints "hello, world!"

Perl не имеет семантики передачи по имени, но вы можете эмулировать их, используя хэш. Метод вызова функции такой же. Вы разыменовываете это.

sub a { print @_ }

sub b {
    my %arg = @_;
    $arg{function}->(@{$arg{arguments}});
}

b(function => \&a, arguments => ["hello, world!"]);

ObPerl6: Perl 6 будет иметь семантику передачи по имени.

4 голосов
/ 05 августа 2009

Вы можете получить доступ к ссылкам подпрограмм как \&my_method в Perl и вызывать эти ссылки с помощью $myref->();. Попробуйте это:

perl -e'sub a { print "foo in a"; }; sub b { shift->(); }; b(\&a);'

Удачи!

3 голосов
/ 05 августа 2009

Следуя примеру Эли Кортрайта: если вы используете первую функцию только один раз, вы можете также вызвать b с анонимной функцией, например:

b( sub { print "Hello World\n"; } );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...