В Perl символ ->
имеет два значения.Если за ним следует голое слово $obj->name
или скаляр $obj->$name
, то ->
означает вызов метода.
Если вместо ->
следует открывающая фигурная скобка, то это разыменование, согласноследующая таблица:
$obj->(...) # dereference as code, which calls the subroutine
$obj->[...] # dereference as array, which accesses an element
$obj->{...} # dereference as hash, which accesses an element
Когда ->
разыменовывает значение, perl проверит, является ли значение типом, указанным в фигурной скобке, или оно может быть приведено к этому типу через перегрузку.Таким образом, ->(
в вашем примере означает, что perl попытается преобразовать $object_ref
в ссылку на код и, возможно, потерпит неудачу, выдав ошибку.
Если ->
является вызовом метода, тогда perl делаетчто-то вроде:
if (reftype $name eq 'CODE') { # if $name is code, ignore $object_ref's type
$name->($object_ref) # call the coderef in $name, with $object_ref
} # followed by any other arguments
elsif (my $code = $object_ref->can($name)) { # otherwise, try to look up the
# coderef for the method named $name in $object_ref's namespace and then
$code->($object_ref) # call it with the object and any other arguments
}
else {die "no method $name on $object_ref"}
Просто, чтобы прояснить ситуацию:
sub foo {"foo(@_)"}
my $foo = \&foo;
say foo 'bar'; # 'foo(bar)'
say $foo->('bar'); # 'foo(bar)'
say 'bar'->$foo; # 'foo(bar)'
и
sub Foo::bar {"Foo::bar(@_)"}
my $obj = bless [] => 'Foo';
my $method = 'bar';
say $obj->bar(1); # Foo::bar($obj, 1)
say $obj->$method(1); # Foo::bar($obj, 1)