9

When executing the statement $obj->method();, perldiag says that Perl needs to know what package the method belongs to. That's why it needs to be blessed:

Can't call method "%s" on unblessed reference

(F) A method call must know in what package it's supposed to run. It ordinarily finds this out from the object reference you supply, but you didn't supply an object reference in this case. A reference isn't an object reference until it has been blessed. See perlobj.

Because of this, it isn't possible to do the following:

my $data = [
             [ 1, 2, 3 ],
             [ 4, 5, 6 ],
           ];

$data->process( @params );  # Can't call method "process" on unblessed reference

Then why does it work with a coderef?:

my $process = \&process;    # Same method as before
$data->$process( @params ); # Works fine now
Zaid
  • 36,680
  • 16
  • 86
  • 155
  • also, the lhs of `->` does not even have to be a reference when the rhs is code: `my $add = sub {$_[0] + $_[1]}; say 1->$add(2);`. Literal references are fine too: `[[1,2,3],[4,5,6]]->$process(@params)` – Eric Strom Nov 15 '11 at 02:17

3 Answers3

22
$variable->method(@args)

just invokes

method($variable, @args)

But in which package should Perl find the method subroutine? If $variable is a blessed reference, Perl will look for the subroutine in the package returned by ref $variable. If $variable is a string and the name of a package, Perl will look for the subroutine in that package name.

In your second example, when you declare

$process = \&process

you have given Perl the reference to the code you want to invoke, so Perl knows to take the call

$variable->$process(@args)

and invoke

$process->($variable, @args)

or

&process($variable, @args)

It is only when $variable is an unblessed reference, and the method name can not be resolved into a code reference, that Perl cannot figure out what to do and punts.

mob
  • 117,087
  • 18
  • 149
  • 283
  • +1 : Makes sense. But is there still ambiguity in a single script that doesn't have multiple packages? – Zaid Nov 14 '11 at 18:48
  • 2
    Every script has multiple packages (try `perl -E 'say for grep/::$/,keys %main::`). But the larger point is that every subroutine call **always** happens with respect to package (except maybe calls to anonymous subs), even if Perl syntax often hides some of the details. There is no mechanism in the compiler to take an unqualified subroutine name and to search all the available namespaces for a matching subroutine name. – mob Nov 14 '11 at 19:06
10

When perl sees $x->$y it compiles it into something like:

if (reftype $y eq 'CODE') {
    $y->($x)
}
else {
    if (my $code_ref = eval {$x->can($y)}) {
        $code_ref->($x)
    }
    else {
       die "error"
    }
}

If $y happens to be a bareword, the first check is always false, and then the else block performs a normal method call.

Eric Strom
  • 39,821
  • 2
  • 80
  • 152
6

In the first example, you're trying to call a method of an array reference by name; the array reference doesn't have any methods, so this doesn't even make sense.

In the second example, you're using similar syntax, but in this case the -> is just syntactic sugar for calling the right-hand parameter with the left-hand parameter as the first argument; it's not calling an instance method, it's simply invoking a subroutine with the parameter specified in a confusing way.

Wooble
  • 87,717
  • 12
  • 108
  • 131