- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

16.5 Indirect Object Syntax

The other way to invoke a method is by using the so-called "indirect object" notation. This syntax was available in Perl 4 long before objects were introduced, and is still used with filehandles like this:

print STDERR "help!!!\n";

The same syntax can be used to call either object or class methods.

my $fred = find Critter "Fred";
display $fred "Height", "Weight";

Notice that there is no comma between the object or class name and the parameters. This is how Perl can tell you want an indirect method call instead of an ordinary subroutine call.

But what if there are no arguments? In that case, Perl must guess what you want. Even worse, it must make that guess at compile time. Usually Perl gets it right, but when it doesn't you get a function call compiled as a method, or vice versa. This can introduce subtle bugs that are hard to detect.

For example, a call to a method new in indirect notation (as C++ programmers are wont to make) can be miscompiled into a subroutine call if there's already a new function in scope. You'd end up calling the current package's new as a subroutine, rather than the desired class's method. The compiler tries to cheat by remembering bareword requires, but the grief when it messes up just isn't worth the years of debugging it will take you to track down such subtle bugs.

There is another problem with this syntax: the indirect object is limited to a name, a scalar variable, or a block, because it would have to do too much lookahead otherwise, just like any other postfix dereference in the language. (These are the same quirky rules as are used for the filehandle slot in functions like print and printf.) This can lead to horribly confusing precedence problems, as in these next two lines:

move $obj->{FIELD};                 # probably wrong!
move $ary[$i];                      # probably wrong!

Those actually parse as the very surprising:

$obj->move->{FIELD};                # Well, lookee here
$ary->move([$i]);                   # Didn't expect this one, eh?

Rather than what you might have expected:

$obj->{FIELD}->move();              # You should be so lucky.
$ary[$i]->move;                     # Yeah, sure.

To get the correct behavior with indirect object syntax, you would have to use a block around the indirect object:

move {$obj->{FIELD}};
move {$ary[$i]};

Even then, you still have the same potential problem if there happens to be a function named move in the current package. The -> notation suffers from neither of these disturbing ambiguities, so we recommend you use it exclusively. However, you may still end up having to read code using the indirect object notation, so it's important to be familiar with it.

ISBN 9781906966027Perl Language Reference ManualSee the print edition