Как я могу вызвать имя функции, определенной в буквальной строке в Perl? - PullRequest
5 голосов
/ 31 января 2012

Если $name='name', почему $object_ref->$name работает, но не $object_ref->('name')?

Ответы [ 3 ]

10 голосов
/ 31 января 2012

В 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)
4 голосов
/ 31 января 2012
$obj->$name       # Method call with no args
$obj->name        # Method call with no args
$obj->$name()     # Method call with no args
$obj->name()      # Method call with no args

$sub->('name')    # Sub call (via ref) with one arg.
sub('name')       # Sub call with one arg.
1 голос
/ 31 января 2012

Синтаксис для вызовов методов: $object->method или $object->$method. Синтаксис, который вы дали, однако, может использоваться для $sub_ref->(@param).

...