If a constant value is given for an identifier, do not diminish the maintainability of the code in which it is used by assuming its value in expressions. Simply giving the constant a name is not enough to ensure modifiability; you must be careful to always use the name, and remember that the value can change.
Noncompliant Code Example
This noncompliant example first provides a constant value $BufferSize
, set to 512. This constant can later be used to buffer data read in from a file. But then code example defeats the purpose of defining $BufferSize
as a constant by assuming its value in the subsequent expression:
our $BufferSize = 512; # ... my $nblocks = 1 + (($nbytes - 1) >> 9); # because $BufferSize = 512 = 2^9
The programmer's assumption underlying this code is that "everyone knows that $BufferSize
equals 512," and right-shifting 9 bits is the same (for positive numbers) as dividing by 512. However, if $BufferSize
changes to 1024 on some systems, the subsequent expression must also be updated and can be overlooked easily. This makes modifications of constants difficult and error prone.
Compliant Solution
This compliant solution uses the identifier assigned to the constant value in the expression.
my $nblocks = 1 + (($nbytes - 1) / $BufferSize;
Risk Assessment
Assuming the value of an expression diminishes the maintainability of code and can produce unexpected behavior under any circumstances in which the constant changes.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP03-PL |
low |
unlikely |
medium |
P2 |
L3 |
Automated Detection
Tool |
Diagnostic |
---|---|
Perl::Critic |
ValuesAndExpressions::ProhibitMagicNumbers |
Related Guidelines
EXP07-C. Do not diminish the benefits of constants by assuming their values in expressions |
|
EXP07-CPP. Do not diminish the benefits of constants by assuming their values in expressions |
Bibliography
[CPAN]. Elliot Shank, Perl-Critic-1.116. ProhibitMagicNumbers.
[Wall 2011] perlfunc