The 'indirect object call syntax' is a grammatical mechanism used by Perl to parse method calls. It is commonly used to emulate other language syntax. For instance, if a class Class
has a constructor named new
, then both of these statements invoke this constructor:
Code Block |
---|
my $obj1 = Class->new; # 'object-oriented' syntax my $obj = new Class; # 'indirect object' syntax |
The perlobj manpage [perlobj manpageWall 2011] states the following:
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.
...
Code Block | ||||
---|---|---|---|---|
| ||||
{ package Class; sub new { my $class = shift; my $arg = shift; my $self = bless( {Arg=>$arg}, $class); print "Class::new called with $arg\n"; return $self; } } sub new { my $arg = shift; print "::new called with $arg\n"; } my $class_to_use = Class; my $b1 = new Something; # Invokes global new my $b2 = new Class Something; # Invokes Class::new my $b3 = new $class_to_use; # Surprise! invokes global new! |
In this code, the last three statements use " indirect object " syntax to invoke a new
subroutine. However, the Perl interpreter can easily misinterpret which subroutine is actually meant to be invoked. This behavior can be especially dangerous if the methods to be invoked live in different packages.
...
In this compliant solution, the final three statements all use 'direct' object syntax, explicitly making their intent clear to both the developer and the Perl interpreter.
Code Block | ||||
---|---|---|---|---|
| ||||
# ... my $class_to_use = Class; my $b1 = new( Something); # Invokes global new my $b2 = Class->new( Something); # Invokes Class::new my $b3 = $class_to_use->new( Something); # Invokes Class::new |
...
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OOP32-PL | lowLow | probableProbable | mediumMedium | P6P4 | L3 |
Automated Detection
Tool | Diagnostic |
---|---|
Perl::Critic | Objects::ProhibitIndirectSyntax |
Bibliography
...
"Prototypes |
---|
...
," p. 194 |
---|
[CPAN] |
...
...
Bar, Graham. List::Utils http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/ | |
[CPAN] | Elliot Shank, Perl-Critic-1.116 Objects::ProhibitIndirectSyntax |
[Wall 2011] | perlobj |
...
02. Expressions EXP06-PL. Do not use the two-argument form of open()