2012-01-30 8 views

Odpowiedz

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

Składnia dla wywołań metod to $object->method lub $object->$method. Składnia, którą podałeś, może być jednak użyta dla $sub_ref->(@param).

9

W języku Perl symbol -> ma dwa znaczenia. Jeśli po nim jest wpisane $obj->name lub skalarne $obj->$name, wówczas -> oznacza wywołanie metody.

Jeśli zamiast -> następuje nawias klamrowy otwarcia, to jest to dereference, zgodnie z poniższą tabelą:

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

Kiedy -> jest dereferencing wartość, Perl będzie sprawdzić, czy wartość jest albo typ wskazany przez nawias klamrowy, albo może być wymuszony na ten typ przez przeciążenie. Tak więc ->( w twoim przykładzie oznacza, że ​​perl spróbuje przekonwertować $object_ref na odwołanie do kodu, i prawdopodobnie zakończy się niepowodzeniem, zgłaszając błąd.

Jeśli -> jest wywołanie metody, a następnie perl robi coś takiego:

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

tylko do rzeczy jaśniej:

sub foo {"foo(@_)"} 

my $foo = \&foo; 

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

i

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)