Use Strict, Warnings, and Diagnostics in Perl

Perl is a very flexible language and it provides engineers the most tolerant. However we can request it treat us more strictly. In this post, I will conclude how can we program Perl strictly and debug Perl in an effective way.

Perl has three pragmas specifically designed to ensure your Perl scripts are elegant:

user warnings;

use diagnostics;

use strict;

 

Perl’s warnings,

If you find that your program can run smooth but its result is not as expected, after a carefully review of the code, you still have no idea where it goes wrong. Under this circumstances you can use:

Run the script with -w:

perl -w program

Enable the warnings in your first line:

#! /usr/bin/perl -w

or (perl -version ge 5.6)

#! /usr/bin/perl -w

use warnings;

The Warnings option will help us finding typing mistakes in program like use a string as a number.

For example,

#! /usr/local/bin/perl -w

##################################
# Warnings option
##################################
my $iamnumber = “12345abc678”;
my $i = 123;
my $i2 = $i + $iamnumber;
print “$i2 \n”;

Output:

(luhuang) public_html- ./debug.pl
Argument “12345abc678” isn’t numeric in addition (+) at ./debug.pl line 8.
12468
(luhuang) public_html-

The calculation result is not a number however it didn’t faile the program, but with the warnings option, it complaint,

Argument “12345abc678” isn’t numeric in addition (+) at ./debug.pl line 8.

Above is the detailed list of warnings from http://perldoc.perl.org/perldiag.html

(W) A warning (optional)
(D) A deprecation (enabled by default)
(S) A severe warning (enabled by default)

(W) A warning (optional):

Missing argument in %s
Missing argument to -%c
(Did you mean &%s instead?)
(Did you mean “local” instead of “our”?)
(Did you mean $ or @ instead of %?)
‘%s’ is not a code reference
length() used on %s
Misplaced _ in number

(D) A deprecation (enabled by default):

defined(@array) is deprecated
defined(%hash) is deprecated
Deprecated use of my() in false conditional
$# is no longer supported

(S) A severe warning (enabled by default)

elseif should be elsif
%s found where operator expected
(Missing operator before %s?)
(Missing semicolon on previous line?)
%s never introduced
Operator or semicolon missing before %s
Precedence problem: open %s should be open(%s)
Prototype mismatch: %s vs %s
Warning: Use of “%s” without parentheses is ambiguous
Can’t open %s: %s

 

Perl’s diagnostics,

If you don’t understand the warning message, you can use ‘diagnostics’:

#! /usr/bin/perl

use diagnostics;

Output:

(luhuang) public_html- ./debug.pl
Argument “12345abc678” isn’t numeric in addition (+) at ./debug.pl line 8 (#1)
(W numeric) The indicated string was fed as an argument to an operator
that expected a numeric value instead. If you’re fortunate the message
will identify which operator was so unfortunate.

12468

(The diagnostics option has a side effect: It will consume more memory resource so in your production code you should remove it)

 

Perl’s strict,

You can use pragma ‘user strict’ to force yourself to program Perl language in a strict way. With use strict Perl complains if you try to use a variable that you have not previously declared.

For example:

#! /usr/local/bin/perl
use diagnostics;
$i = 123; # It is fine.
print “$i \n”;

Output:

(luhuang) public_html- ./debug.pl
123

However after I replaced diagnostics with strict:

(luhuang) public_html- ./debug.pl
Global symbol “$i” requires explicit package name at ./debug.pl line 3.
Global symbol “$i” requires explicit package name at ./debug.pl line 4.
Execution of ./debug.pl aborted due to compilation errors.

The explanation for this error is:

This generates a compile-time error if you access a variable that wasn’t declared via “our” or “use vars”, localized via “my()”, or wasn’t fully qualified.

So here the problem is, as I didn’t declare it as ‘my’ then Perl treated it as a ‘use vars’ and package name is missing!

Obviously, use strict should (must) be used when we want to program Perl properly which can be forcing declaration, being explicit on strings and subs.

 

Conclusion:

In Perl, we can use the pragmas of warnings, diagnostics, and strict to catch many errors or potential errors sooner that they would be caught otherwise, which makes it easier to find the root causes of the errors. I think even experienced programmers make syntax erros, so in our production code, we should use ‘strict’ and ‘warnings’ unless we know exactly they are working totally fine!