6

If $name='name' why does $object_ref->$name work but not $object_ref->('name')?

Toto
  • 89,455
  • 62
  • 89
  • 125
JD.
  • 2,361
  • 6
  • 25
  • 38

3 Answers3

11

In Perl, the symbol -> has two meanings. If followed by a bareword $obj->name or a scalar $obj->$name then -> means method call.

If instead the -> is followed by an opening brace, then it is a dereference, according to the following table:

$obj->(...) # dereference as code,  which calls the subroutine
$obj->[...] # dereference as array, which accesses an element
$obj->{...} # dereference as hash,  which accesses an element

When -> is dereferencing a value, perl will check to see if the value is either the type indicated by the brace, or if it can be coerced into that type via overloading. So the ->( in your example means perl will try to convert $object_ref into a code reference, and will probably fail, throwing an error.

If the -> is a method call, then perl does something like:

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"}

Just to make things clearer:

sub foo {"foo(@_)"}

my $foo = \&foo;

say foo 'bar';     # 'foo(bar)'
say $foo->('bar'); # 'foo(bar)'
say 'bar'->$foo;   # 'foo(bar)'

and

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)
Eric Strom
  • 39,821
  • 2
  • 80
  • 152
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.
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

Syntax for method calls is $object->method or $object->$method. The syntax you gave, however, can be used for $sub_ref->(@param).

choroba
  • 231,213
  • 25
  • 204
  • 289