Perl 5 has no operator new
; a constructor in Perl 5 is anything which returns an object. By convention, constructors are class methods named new()
, but you can choose anything you like. Several old Perl 5 object tutorials promote the use of C++ and Java-style constructor calls:
... instead of the obvious method call:
These syntaxes produce equivalent behavior, except when they don't.
In the indirect object form (more precisely, the dative case) of the first example, the verb (the method) precedes the noun to which it refers (the object). This is fine in spoken languages, but it introduces parsing ambiguities in Perl 5.
As the method name is a bareword (barewords), the parser must divine the proper interpretation of the code through the use of several heuristics. While these heuristics are well-tested and almost always correct, their failure modes are confusing. Worse yet, they depend on the order of compilation of code and modules.
Parsing difficulty increases when the constructor takes arguments. The indirect style may resemble:
... thus making the name of the class look like a function call. Perl 5 can disambiguate many of these cases, but its heuristics depend on which package names the parser has seen, which barewords it has already resolved (and how it resolved them), and the names of functions already declared in the current package.
Imagine running afoul of a prototyped function (prototypes) with a name which just happens to conflict somehow with the name of a class or a method called indirectly. This is rare, but so unpleasant to debug that it's worth avoiding indirect invocations.
Another danger of the syntax is that the parser expects a single scalar expression as the object. Printing to a filehandle stored in an aggregate variable seems obvious, but it is not:
Perl will attempt to call say
on the $config
object.
print
, close
, and say
--all builtins which operate on filehandles--operate in an indirect fashion. This was fine when filehandles were package globals, but lexical filehandles (lexical_filehandles) make the indirect object syntax problems obvious. To solve this, disambiguate the subexpression which produces the intended invocant:
Direct invocation notation does not suffer this ambiguity problem. To construct an object, call the constructor method on the class name directly:
This syntax still has a bareword problem in that if you have a function named CGI
, Perl will interpret the bareword class name as a call to the function, as:
While this happens rarely, you can disambiguate classnames by appending the package separator (::
) or by explicitly marking class names as string literals:
Yet almost no one ever does this.
For the limited case of filehandle operations, the dative use is so prevalent that you can use the indirect invocation approach if you surround your intended invocant with curly brackets. If you're using Perl 5.14 (or if you load IO::File
or IO::Handle
), you can use methods on lexical filehandlesAlmost no one does this for print
and say
though..
The CPAN module Perl::Critic::Policy::Dynamic::NoIndirect
(a plugin for Perl::Critic
) can identify indirect invocations during code reviews. The CPAN module indirect
can identify and prohibit their use in running programs:
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 137:
-
Deleting unknown formatting code N<>