Perl lets you call object methods in two different ways:

  • $obj->method()
  • method $obj

The latter form is usually called only for things like clone $obj, which is pretty ugly. For more about indirect object syntax and some of the pain it causes, see When Is Backwards-Compatibility Not Worth It?.

It's funny that Max posted that blog entry the other day, because I just was shown a problem that was caused indirectly by it. Mike O'Regan showed me some code that he was surprised even compiled, because it certainly wasn't working.

sub custom_sort {
$a->{foo} cmp $b->{foo}
a$->{bar} cmp b$->{bar}

See the a$ instead of $a? Yuck. But it compiles just fine. Why? Well, let's see what B::Deparse decompiles it out as:

$ perl -MO=Deparse
sub custom_sort {
return $$a{'foo'} cmp $$b{'foo'} || $-->a > {'bar'} cmp $-->b > {'bar'};
} syntax OK

Turns out that it's calling method a on the object $- and then seeing if that is greater than {'bar'}. Double-ugh.

Perl 6 still has indirect object syntax, but you must follow it with a colon, as in method $obj: @args. Larry says in Perl 6 it's completely unambiguous.