JD.*_*JD. 5 perl interpolation reference function
如果$name='name'
为什么$object_ref->$name
工作但不是$object_ref->('name')
?
Eri*_*rom 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
Run Code Online (Sandbox Code Playgroud)
当->
取消引用一个值时,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"}
Run Code Online (Sandbox Code Playgroud)
只是为了让事情更清楚:
sub foo {"foo(@_)"}
my $foo = \&foo;
say foo 'bar'; # 'foo(bar)'
say $foo->('bar'); # 'foo(bar)'
say 'bar'->$foo; # 'foo(bar)'
Run Code Online (Sandbox Code Playgroud)
和
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)
Run Code Online (Sandbox Code Playgroud)
$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.
Run Code Online (Sandbox Code Playgroud)