Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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|AA. Bibliography#Manpages] \] states the following:{quote}

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.

{quote}Consequently, indirect object syntax shall not be used.h2.

Noncompliant Code Example

This noncompliant code example demonstrates some of the hazards of using indirect call syntax.{

Code Block

...

bgColor

...

#ffcccc

...

lang

...

perl

...

{

...


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! 

{code}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 can be especially dangerous if the methods to be invoked live in different packages.h2.

Compliant Solution

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

...

bgColor

...

#ccccff

...

lang

...

perl

...

# ...

...



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

...


...

Risk Assessment

...

Recommendation

...

Severity

...

Likelihood

...

Remediation Cost

...

Priority

...

Level

...

...

OOP32-PL

...

low

...

probable

...

medium

P6

L3

Automated Detection

h2. Automated Detection

...

Tool

Diagnostic

Perl::Critic

...

Objects::ProhibitIndirectSyntax

...

...

Bibliography

\[[Conway 05|AA. Bibliography#Conway 05]\] pg. 194 "Prototypes"
\ [[Wall 2011|AA. Bibliography#Manpages] \] [perlobj|http://perldoc.perl.org/perlobj.html]
\[ [CPAN|AA. Bibliography#CPAN]\] [Elliot Shank, Perl-Critic-1.116|http://search.cpan.org/~elliotjs/ Perl-Critic-1.116/] [Objects::ProhibitIndirectSyntax|http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Policy/Objects/ProhibitIndirectSyntax.pm]
\[ [CPAN|AA. Bibliography#CPAN]\] Bar, Graham. [List::Utils|http://search.cpan.org/~gbarr/Scalar-List-Utils-1.23/lib/List/Util.pm]
http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/

...

----
[!CERT Perl Secure Coding Standard^button_arrow_left.png!|EXP06-PL. Do not use an array in an implicit scalar context]      [!CERT Perl Secure Coding Standard^button_arrow_up.png!|02. Expressions]      [!CERT Perl Secure Coding Standard^button_arrow_right.png!|Image Added      02. Expressions      EXP06-PL. Do not use the two-argument form of open()]