如何在perl中调用文字字符串中定义的函数名?

时间:2012-01-30 22:58:09

标签: perl function reference interpolation

如果$name='name'为什么$object_ref->$name可以工作,而不是$object_ref->('name')

3 个答案:

答案 0 :(得分:10)

在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)

答案 1 :(得分:4)

$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.

答案 2 :(得分:1)

方法调用的语法是$object->method$object->$method。但是,您提供的语法可用于$sub_ref->(@param)