strict, warnings and diagnostics

Contents
use strict
use warnings
diagnostics and splain
Syntax checks and perlcritic

use strict

Perl is permissive by default: an undeclared variable simply springs into existence, and a typo in a variable name silently creates a second variable. use strict turns those mistakes into hard errors.

use strict; use warnings; my $name = "Ada"; my @items = ("pen", "cup"); my %count = (pen => 1); print $name, "\n"; print scalar @items, "\n"; print $count{pen}, "\n";

Every variable is introduced with my, which gives it lexical scope that ends at the closing brace of the enclosing block. Drop the declaration and the program stops before it does any damage:

use strict; $name = "Ada";

Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at demo.pl line 2. Execution of demo.pl aborted due to compilation errors.

strict is really three switches in one: vars requires declarations, subs requires parentheses or a predeclared name for every function call, and refs forbids symbolic references. The default use strict enables all three, and that is what you want.

use warnings

Warnings are the other half: they do not stop the program, they tell you that a value was missing, a string looked like a number, or a result was thrown away. Most of them point at real bugs.

use warnings; my $total; print $total + 1, "\n"; my @scores = (10, 20); print $scores[5], "\n";

Use of uninitialized value $total in addition (+) at demo.pl line 4. Use of uninitialized value within @scores in print at demo.pl line 7.

Instead of the old -w flag on the shebang line, put use warnings in the file. The flag applies to every module the program loads, including ones you did not write; the pragma applies only to the file that uses it.

In development you can make selected warnings fatal, so the program dies at the first sign of trouble instead of printing a line and carrying on:

use warnings FATAL => 'all'; my $x; print $x * 2;

Use of uninitialized value $x in multiplication (*) at demo.pl line 4.

Turn fatal warnings off before shipping a tool that reads untrusted data, or one odd input will end the run.

diagnostics and splain

Some Perl messages are famously terse. The diagnostics pragma replaces each one with a paragraph that explains the cause and the usual fix:

use diagnostics; my %opts; print $opts{port} + 1, "\n";

Use of uninitialized value $opts{"port"} in addition (+) at demo.pl line 4 (#1) (W uninitialized) An undefined value was used as if it were already defined. It was interpreted as a "" or a 0, but maybe it was a mistake. To suppress this warning assign a defined value to your variables.

Loading diagnostics permanently slows a program down, so keep it for a debugging session and delete it afterwards. For one run you can ask the interpreter instead:

perl -Mdiagnostics script.pl

The same text lives in perldoc perldiag, organised by message. Search that page when a message makes no sense: it lists the severity letter, the cause, and the cure for each one.

Syntax checks and perlcritic

You do not have to run a program to know whether it compiles. The -c flag compiles the file and stops, which catches typos, missing modules and broken braces in a second:

perl -c script.pl

script.pl syntax OK

Two more switches help when you cannot see why a line behaves the way it does. -MO=Deparse prints the program after Perl has parsed it, which shows how precedence really grouped your expression. -MData::Dumper can dump a variable from a one-liner during a debug session.

perl -MO=Deparse script.pl

For style and risky constructs, install Perl::Critic and run it at a gentle severity. It flags things like two-argument open, bareword filehandles, and string eval, each with the policy name that explains the rule.

perlcritic --severity 3 script.pl

Code before strictures are enabled at line 3, column 1. See page 429 of PBP. (Severity: 5)

Not every policy is worth obeying in every file. Choose the severity you can live with, read the policy documentation before you change code to please the tool, and leave a comment when you deliberately break a rule.

Next: Options with Getopt::Long

Article author: Arthur Isaev

Related articles
Perl
Perl course: zero to hero in 50 lessons
What is Perl and where it runs
Install Perl and check the version
Your first Perl script
The debugger as a REPL
Scalars and sigils
Numbers
Strings
Interpolation and quoting
Arrays
push, pop, shift and splice
Hashes
keys, values, exists and delete
Scalar and list context
Conditions and comparison
while, for, next and last
foreach and the default variable
Subroutines
Arguments in @_
References
Nested data structures
Regular expressions: match and anchors
Captures and named groups
Substitution with s///
split and join
grep and map
Sort and the Schwartzian transform
Read and write files
File tests and metadata
Directories and paths
die, warn and eval
Modules and Exporter
CPAN and cpanm
Objects with bless
Modern objects with Moo
Testing with Test::More
strict, warnings and diagnostics
Options with Getopt::Long
Environment and %ENV
system, backticks and pipes
One-liners with -n and -p
CSV and TSV processing
JSON with JSON::PP
HTTP clients with HTTP::Tiny
Sockets and IO::Socket
Databases with DBI
Capstone: todo CLI
Capstone: log report
Performance and profiling
Modern Perl tour
Hero roadmap: the whole course on one page
Install Perl on Windows 11
Install Perl on Ubuntu
Install Perl on Rocky Linux
Install Perl on macOS
Install Perl on FreeBSD
Perl in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: