Perl has two contexts in which expressions can be evaluated: scalar, and list. These contexts actually determine what the expression generates. It is recommended that when an expression is evaluated in an unexpected context, that the context be made explicit. Implicit context switching makes programs difficult to read and more error prone.
Noncompliant Code Example
This noncompliant code example tries to print out the elements of an array.
sub print_array { my $array = shift; print "( "; foreach $item (@{$array}) { print "$item , "; } print ")\n"; } my @array; # initialize my $array_ref = @array; print_array( $array_ref);
The developer mistakenly left out the }} indicator when initializing {{$array_ref
. Consequently, it contains not a reference to the array, but rather the number of elements in the array. When passed to the print_array()
subroutine, this program prints an empty array.
Compliant Solution
This compliant solution initializes $array_ref
correctly.
my $array_ref = \@array; print_array( $array_ref);
Noncompliant Code Example
This noncompliant code example prints the number of elements in an array.
my @array; # initialize my $cardinality = @array; print "The array has $cardinality elements\n";
While this program works correctly, there are less ambiguous ways to obtain the number of elements of an array.
Compliant Solution (scalar()
)
This compliant solution uses the scalar()
builtin subroutine to obtain the number of elements of an array.
my $cardinality = scalar( @array); print "The array has $cardinality elements\n";
This compliant solution again evaluates @array
in scalar context just like the noncompliant code example. However the scalar()
makes this evaluation explicit, removing any doubt as to the programmer's intentions.
Compliant Solution ($#
)
This compliant solution uses the $#
operator to obtain the number of elements of an array.
my $cardinality = $#array + 1; print "The array has $cardinality elements\n";
Risk Assessment
Evaluating an array or hash in improper contexts can lead to unexpected and surprising program behavior.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP05-PL |
low |
unlikely |
medium |
P2 |
L3 |
Automated Detection
Tool |
Diagnostic |
---|---|
B::Lint |
context |
Bibliography
http://perldoc.perl.org/B/Lint.html
Malcolm Beattie, mbeattie@sable.ox.ac.uk.
[Beattie]
[CPAN]. Elliot Shank, Perl-Critic-1.116. ProhibitBooleanGrep.
[Conway 2005], pg 71
[Wall 2011] perlfunc
EXP11-C. Do not apply operators expecting one type to data of an incompatible type 03. Expressions (EXP) EXP13-C. Treat relational and equality operators as if they were nonassociative