Perl Part I · Module 1 · Introduction to Perl
use warnings: Letting Perl Tell You It Is Suspicious
use strict refuses to compile code whose names do not make sense. use warnings is its complement: it lets the program run and comments on values that look wrong while it does. The difference matters more than it sounds, because a warning does not stop anything — Perl tells you the value was suspicious and then goes on to produce the answer that suspicious value led to. Two messages account for most of what you will ever see, and both are saying the same thing in different words: the data was not the shape your code assumed.
Foundation12 min readPerlPart IFundamentalsuse warningsDebugging
Part I · Module 1 · Chapter 1.11 · use warnings: Letting Perl Tell You It Is Suspicious
1. Warnings Versus strict
Chapter 1.10 covered a pragma that makes Perl refuse. This one makes Perl comment. The division is clean and worth holding onto:
use strict | use warnings | |
|---|---|---|
| What it inspects | names, while compiling | values, while running |
| When it acts | compile stage | run stage, as each value is used |
| What happens | the program does not run | the program continues |
| Where the message goes | your terminal, then it stops | STDERR, and output keeps coming |
That last row is the one to internalise. A warning is information, not a failure. The program carries on, produces output, and exits 0. If the suspicious value fed a number you were going to report, that number is still reported.
So use warnings does not protect you. It tells you where to look.
2. The First Message: Uninitialized Value
A variable declared but never given a value holds nothing. Use it in arithmetic and Perl says so:
use strict;
use warnings;
my $n;
print $n + 1, "\n";Use of uninitialized value $n in addition (+) at uninit.pl line 5.1Perl treated the empty variable as 0, added 1, and printed 1. The exit status is 0: as far as any caller is concerned, this run succeeded.
The message is unusually precise and worth reading in full, because every part of it is useful:
$n— it names the variable. On a line with several, this tells you which one.in addition (+)— it names the operation. The same variable might be fine elsewhere.at uninit.pl line 5— file and line.
In real work this message almost always means one thing: a value you expected to be there was not. A field that was absent from an input line, a setting nobody supplied, a result that was never computed. The 1 that got printed is arithmetic on an absence.
3. The Second Message: Isn't Numeric
The other common case is a value that is there and is not a number:
use strict;
use warnings;
my $field = "N/A";
print $field + 0, "\n";Argument "N/A" isn't numeric in addition (+) at not-numeric.pl line 5.0Again the program completed and exited 0, and again the printed answer — 0 — is wrong in a way that looks entirely plausible.
Perl's willingness to treat "N/A" as 0 is deliberate language design, not a bug; Chapter 2.6 covers the conversion rules properly. What matters here is the engineering reading of the message: a field you treated as a number was text. In Part II that is the single most common cause of a report full of zeros — a tool wrote N/A, or -, or left the column empty, and the parser added it to a total.
4. The Same Programs Without Warnings
Remove the pragma from both and run them again:
use strict;
my $n;
print $n + 1, "\n";
my $f = "N/A";
print $f + 0, "\n";1
0No messages. Exit status 0. The same two wrong answers, now with nothing at all to indicate that anything was unusual.
This is the argument for the pragma, and it is a different argument from the one for use strict. Strict changes what your program does — it stops running. Warnings change only what you know. The values, the output and the exit status are identical either way.
5. A Warning Is Not a Failure
It follows that warnings are only useful if someone reads them, and that creates two real hazards.
They go to STDERR. Per Chapter 1.7, that is correct — they are messages about the run, not results. But it also means a job that captures only STDOUT discards every warning, and a job that redirects STDERR to a file produces one nobody opens.
They do not change the exit status. A run that warned a thousand times still reports success. Nothing downstream will notice.
So the honest position is: use warnings is excellent during development, when you are watching the terminal, and insufficient on its own in automation. Making a specific warning fatal — so that it stops the program like an error — is possible, and Chapter 14.6 covers it. That is the tool for the automation case.
6. Reading a Warning Properly
A short procedure, which works for any warning and not just the two above.
- Read the variable name. It tells you which value on the line was the problem.
- Read the operation.
in addition (+),in concatenation (.) or string,in print— this narrows a long line to one part of it. - Ask where the value came from, not why Perl objected. The warning is about a symptom; the cause is upstream, in whatever was supposed to supply the value.
- Decide what the absence means. This is the engineering judgement, and it is not Perl's to make. Is a missing field zero, or is it unknown? Those are different, and treating the second as the first is how a report ends up confidently wrong.
You saw step 4 already: Chapter 1.7 read a line from STDIN that was not there, and the warning named in concatenation (.) or string rather than addition. Same procedure, different operation.
7. Mistakes and How They Look
Treating warnings as noise. The usual reason is volume — a legacy script emits hundreds, so they get ignored as a class. The fix is not to switch them off but to drive the count to zero, because a warning only carries information if its presence is unusual.
Silencing the message instead of fixing the data. Perl has no warnings for a block, and it is occasionally correct. Used to quieten the two messages in this chapter, it hides exactly the information you need.
Expecting a warning to stop the program. It does not. If the condition should be fatal, make it fatal — see Chapter 14.6 — rather than hoping someone reads the log.
Assuming no warnings means correct. Neither pragma inspects your logic. A program with clean output and a wrong algorithm warns about nothing.
8. What You Should Be Able to Say Now
use strictinspects names while compiling and refuses;use warningsinspects values while running and comments.- A warning does not stop the program, does not change the exit status, and goes to STDERR.
Use of uninitialized valuemeans a value you expected was absent; Perl used 0 or an empty string instead.Argument "..." isn't numericmeans a value that was present was not a number; Perl used 0.- Without the pragma the same wrong answers are produced silently — the values do not change, only your knowledge of them.
- In automation, reading warnings is unreliable; making the ones that matter fatal is the real answer, and that is Chapter 14.6.
9. Exercise
Exercise 1 — both messages, both halves. Write uninit.pl and not-numeric.pl from §2 and §3 and run each. Then delete use warnings from both and run them again. Record the four outputs and all four exit statuses.
Exercise 2 — separate the streams. Run the warning version of either script with 2>/dev/null, using Chapter 1.7's redirection. Explain in one sentence what a calling program that reads only STDOUT would conclude about that run.
Exercise 3 — read the operation. Write a script where an uninitialized variable is used inside a double-quoted string rather than in arithmetic. Predict how the message will differ from §2's, then run it and compare the wording.
Exercise 4 — make the judgement. A log line is missing its error-count field, so your script warns Use of uninitialized value and reports 0 errors. Argue in two or three sentences for whether the right answer is 0, or something else — and say what your script should do about it.
10. Summary
use warningscomments; it does not refuse. The program runs to completion and exits 0 regardless.Use of uninitialized valuemeans an expected value was absent and Perl substituted 0 or an empty string.Argument "..." isn't numericmeans a present value was text, and Perl used 0 — the usual cause of a report full of zeros.- Without the pragma the answers are identical and silent. Only your knowledge changes, which is exactly why you keep it on.
- Warnings go to STDERR and do not affect exit status, so automation needs fatal warnings rather than hope.
- Read the name, then the operation, then look upstream — and decide deliberately what a missing value means.
The last three chapters of this module are about diagnosis. Chapter 1.12 takes the error messages you have now seen several times and teaches you to read any of them systematically.
Where this fits
Part of the Perl curriculum.
