Syntactic Snafus with Indirect Objects
One syntax will often be more readable than the other. The indirect object syntax
is less cluttered but suffers from several forms of syntactic ambiguity.
The first is that the LIST part of an
indirect object invocation is parsed the same as any other list
operator. Thus, the parentheses of:
enchant $sword ($pips + 2) * $cost;
are assumed to surround all the arguments, regardless of what comes afterward. It would therefore be equivalent to this:
($sword–>enchant($pips + 2)) * $cost;
That’s unlikely to do what you want: enchant is only being called with $pips + 2, and the method’s return value is
then multiplied by $cost. As with
other list operators, you must also be careful of the precedence of
&& and || versus and and or—if you disdain parentheses.
For example, this:
name $sword $oldname || "Glamdring"; # can’t use "or" here!
becomes the intended:
$sword–>name($oldname || "Glamdring");
but this:
speak $mage "friend" && enter(); # should’ve been "and" here!
becomes the dubious:
$mage–>speak("friend" && enter());which could be fixed by rewriting into one of these equivalent forms:
enter() if $mage–>speak("friend");
$mage–>speak("friend") && enter();
speak $mage "friend" and enter();The second syntactic infelicity of the indirect object form is
that its INVOCANT is limited to a name, an
unsubscripted scalar variable, or a block.[145] As soon as the parser sees one of these, it has its
INVOCANT, so it starts looking for its
LIST. So these invocations:
move ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access