Анонимные подпрограммы могут использоваться для всех видов вещей.
Обратные вызовы для систем обработки событий:
my $obj = Some::Obj->new;
$obj->on_event(sub {...});
Итераторы:
sub stream {my $args = \@_; sub {shift @$args}}
my $s = stream 1, 2, 3;
say $s->(); # 1
say $s->(); # 2
Функции высшего порядка:
sub apply (&@) {
my $code = shift;
$code->() for my @ret = @_;
@ret
}
my @clean = apply {s/\W+/_/g} 'some string', 'another string.';
say $clean[0]; # 'some_string'
Создание псевдонимов:
my $alias = sub {\@_}->(my $x, my $y);
$alias[0]++;
$alias[1] = 5;
say "$x $y"; # '1 5''
Динамическое программирование с замыканиями (например, создание набора подпрограмм, которые отличаются незначительно):
for my $name (qw(list of names)) {
no strict 'refs';
*$name = sub {... something_with($name) ...};
}
Не существует ситуации, когда анонимная подпрограмма может делать что-либо, чтоИменованная подпрограмма не может.Конструктор my $ref = sub {...}
эквивалентен следующему:
sub throw_away_name {...}
my $ref = \&throw_away_name;
без необходимости выбора уникального 'throw_away_name' для каждой подпрограммы.
Эквивалентность также идет другим путем,sub name {...}
эквивалентно:
BEGIN {*name = sub {...}}
Таким образом, кроме имени, ссылка на код, созданная любым методом, одинакова.
Для вызова ссылки на подпрограмму вы можете использовать любойиз следующего:
$code->(); # calls with no args
$code->(1, 2, 3); # calls with args (1, 2, 3)
&$code(); # calls with no args
&$code; # calls with whatever @_ currently is
Вы можете даже использовать ссылки на код в качестве методов для благословенных или необузданных скаляров:
my $list = sub {@{ $_[0] }};
say for [1 .. 10]->$list # which prints 1 .. 10