The LifeKeeper for Linux v9.8.0 release includes an upgraded Perl version from 5.8.8 to 5.32.1. The new version has many new features and enhancements. The new features in 5.32.1 can be found in perl5320delta – what is new for perl v5.32.0 – Perldoc Browser. For a more concise Perl 5 history, see Perl 5 version history – Wikipedia. With these enhancements, Perl 5.32.1 has fixed a number of bugs and tightened up some of the coding practices that led to failures or unexpected results. Here are notes on some best practices to follow for reliable code, as well as things to watch out for or avoid as we transition from Perl 5.8.8 to Perl 5.32.1.
All code should have the following:
use strict;
use warnings;
These will point out almost all errors or questionable code, some of which may have worked in the past, but were deprecated in Perl 5.8.8, and will no longer function under Perl 5.32.1.
no warnings ‘uninitialized’;
The no warnings ‘uninitialized’ pragma allows uses of undef, which is normal Perl style and doesn’t need to be unnecessarily restricted. Additional no warnings pragmas may be used in legacy code where changing the code is too risky or burdensome (“no warnings” should be avoided as much as possible).
Below are some common examples of code that may have worked in the past but with Perl 5.32.1 now produce warnings, errors, and/or do not function correctly at all. As long as “use strict” and “use warnings” are enabled, all the things listed below will give a warning or error message under Perl 5.32.1 (some of these will also produce warnings on Perl 5.8.8):
Implicit split into @_ - no longer works (must be fixed)
Incorrect: map { split /\001/; $_[3] }
Correct: map { @_ = split /\001/; $_[3] }
Incorrect: split /\001/, $ins;
Correct: @_ = split /\001/, $ins;
The implicit split must be fixed, since @_ no longer gets set by split automatically.
Don’t use defined with hashes and arrays - no longer works (must be fixed)
Incorrect: if (defined(%hash))
Correct: if (%hash)
Incorrect: if (defined(@array))
Correct: if (@array)
Defined no longer works on hashes and arrays. In almost all cases, the check you want to do is just a simple “if” check.
@INC perl include path no longer automatically includes “.”
Incorrect: my $rule = do ‘t/test.rule’;
Correct: my $rule = do ‘./t/test.rule’;
Includes of relative paths have to explicitly specify “.” at the beginning (unless you’ve already put “.” in @INC manually).
Variable declarations require package names or scope specifiers.
Incorrect: @ISA = qw(RKBase);
Correct: our @ISA = qw(RKBase);
Correct: @NASBase::ISA = qw(RKBase);
Even Better: use parent ‘RKBase’; # (from Perl 5.10 onward, this is the preferred method for doing the above @ISA setting)
In the above, @ISA is a global, and requires either the our specifier to specify that it’s global, or an explicit package name.
Hashes cannot be used as references
Incorrect: %$QueueManagers->{$qmgr}
Correct: $QueueManagers->{$qmgr}
In the above, if $QueueManagers is a hash reference, then the % is superfluous, and now causes a warning in Perl.
Perl switch module deprecated
The Switch.pm module has been dropped from the standard distribution of Perl as of Perl 5.12. Refer to the “Deprecations” section in the following article for further information: http://www.perl.com/pub/2010/04/inside-perl-512.html
The Perl switch statement has been deprecated and the Switch module is not provided with the Steeleye Perl modules starting in LifeKeeper v9.8.0. Consider using if/then/elsif blocks in place of switch statements.
Perl keys routine will return keys in random order
The Perl keys routine will return the keys in a hash (keys %hash) in a random order (beginning in 5.18.0 for security concerns). Where an order is required this should be explicitly implemented in the code using a routine like sort.
Post your comment on this topic.