111

It seems to me that many of the questions in the Perl tag could be solved if people would use:

use strict;
use warnings;

I think some people consider these to be akin to training wheels, or unnecessary complications, which is clearly not true, since even very skilled Perl programmers use them.

It seems as though most people who are proficient in Perl always use these two pragmas, whereas those who would benefit most from using them seldom do. So, I thought it would be a good idea to have a question to link to when encouraging people to use strict and warnings.

So, why should a Perl developer use strict and warnings?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
TLP
  • 66,756
  • 10
  • 92
  • 149
  • 15
    I always wonder for stuff like this why they don't just make it the default and have the dev actually have to actively loosen stuff, where is the `use loose;` – Paul Tyng Nov 05 '11 at 23:08
  • I've never heard anyone refer to them as training wheels; they're just mechanisms to avoid shooting yourself in the foot. They should really be hard baked into the language so that they can't be turned off. – El Yobo Nov 05 '11 at 23:08
  • 1
    I don't know anything about perl, and you're certainly right about this. But then, why is it not the default configuration? Why not force the developers to use something like "use nonstrict; use letmeprogramlikeapig;" if they really want the current default? – JB Nizet Nov 05 '11 at 23:10
  • 16
    Like many cool and useful things Perl started as a hack, as a tool for the guy who invents it. Later it became more popular and an increasing number of unskilled people started using it. This is when you start thinking something like `use strict` was a good idea but backwards compatibility has already become a real problem to you:-( – Daniel Böhmer Nov 05 '11 at 23:15
  • Isn't that just a lame try to gather reputation? Won't upvote... – Daniel Böhmer Nov 05 '11 at 23:17
  • 15
    @JB Nizet, @Paul T., Actually, `use strict;` is on by default when you request the Perl 5.12 (or higher) language. Try `perl -e"use v5.012; $x=123;"`. `no strict;` actually turns it off. – ikegami Nov 06 '11 at 00:04
  • you couldn't have searched very hard http://stackoverflow.com/questions/6421671/is-it-necessary-to-use-warnings-when-already-use-strict http://stackoverflow.com/questions/6395999/which-safety-net-do-you-use-in-perl http://stackoverflow.com/questions/6050031/why-are-use-warnings-use-strict-not-default-in-perl – Joel Berger Nov 06 '11 at 02:59
  • http://stackoverflow.com/search?q=perl+strict+warnings https://www.google.com/search?q=perl+strict+warnings http://joelslinux.blogspot.com/2011/06/use-strict-and-warnings.html – Joel Berger Nov 06 '11 at 03:03
  • 1
    Though in the end your point is true, the more times we say it, maybe the more people will hear. There has been some rumbling lately of trying to make more/better/modern Perl tutorials available and certainly strict/warnings will be on the top of each of these. For mine I plan to have s/w on the top of every snippet, just so that all newbies see it every time – Joel Berger Nov 06 '11 at 03:05
  • @JoelBerger I did not find any specific question regarding my topic on StackOverflow. There are quite a few questions with "strict" and "warnings" in the title, but I do not see how that is relevant to my question. If you can find an older question which exactly covers this question, be sure to link it. – TLP Nov 06 '11 at 03:48
  • 1
    My third one is almost exactly this this question. Repeated: http://stackoverflow.com/questions/6050031/why-are-use-warnings-use-strict-not-default-in-perl – Joel Berger Nov 06 '11 at 04:30
  • 5
    @JoelBerger No, actually it is nothing like it. Just like I said, it only has similar words in the title. *It's for backwards compatibility.* is the first sentence in the accepted answer, how do you propose that applies to my question? – TLP Nov 06 '11 at 05:04
  • 1
    Nevermind, turns out I don't care to fight this battle, the more places that tell n00bs to use strict and use warnings, the better – Joel Berger Nov 06 '11 at 14:06
  • 2
    A better way to enforce good behavior might be `use Perl::Modern;` http://search.cpan.org/~chromatic/Modern-Perl-1.20150127/lib/Modern/Perl.pm – Stanislav Mar 25 '16 at 00:43

8 Answers8

90

For starters, use strict; (and to a lesser extent, use warnings;) helps find typos in variable names. Even experienced programmers make such errors. A common case is forgetting to rename an instance of a variable when cleaning up or refactoring code.

Using use strict; use warnings; catches many errors sooner than they would be caught otherwise, which makes it easier to find the root causes of the errors. The root cause might be the need for an error or validation check, and that can happen regardless or programmer skill.

What's good about Perl warnings is that they are rarely spurious, so there's next to no cost to using them.


Related reading: Why use my?

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 2
    @TLP, I'm not about to make a study to quantify how much it helps. It should suffice to say that they help unconditionally. – ikegami Nov 06 '11 at 19:42
  • 1
    Why is it made optional then if it has so many benefits ? Why not enable it by default (like someone commented above) ? Is it for compatibility reasons ? – Jean Sep 26 '13 at 16:11
  • 4
    @Jean, backwards compatibility. Note that `use strict;` is enabled by default if you use version 5.12 or newer of the language (`use 5.012;`). – ikegami Sep 26 '13 at 16:34
  • @Jean if you are writing a simple script you really don't want to get alerted by warnings about file handler names or for not declaring the variable before using them :-) – user2676847 Aug 17 '14 at 08:51
31

Apparently use strict should (must) be used when you want to force Perl to code properly which could be forcing declarations, being explicit on strings and subs, i.e., barewords or using refs with caution. Note: if there are errors, use strict will abort the execution if used.

While use warnings; will help you find typing mistakes in program like you missed a semicolon, you used 'elseif' and not 'elsif', you are using deprecated syntax or function, whatever like that. Note: use warnings will only provide warnings and continue execution, i.e., it won't abort the execution...

Anyway, it would be better if we go into details, which I am specifying below

From perl.com (my favourite):

use strict 'vars';

which means that you must always declare variables before you use them.

If you don't declare you will probably get an error message for the undeclared variable:

Global symbol "$variablename" requires explicit package name at scriptname.pl line 3

This warning means Perl is not exactly clear about what the scope of the variable is. So you need to be explicit about your variables, which means either declaring them with my, so they are restricted to the current block, or referring to them with their fully qualified name (for ex: $MAIN::variablename).

So, a compile-time error is triggered if you attempt to access a variable that hasn't met at least one of the following criteria:

  • Predefined by Perl itself, such as @ARGV, %ENV, and all the global punctuation variables such as $. Or $_.

  • Declared with our (for a global) or my (for a lexical).

  • Imported from another package. (The use vars pragma fakes up an import, but use our instead.)

  • Fully qualified using its package name and the double-colon package separator.

use strict 'subs';

Consider two programs

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

In both cases we have a test_value() sub and we want to put its result into $a. And yet, when we run the two programs, we get two different results:

In the first program, at the point we get to $a = test_value;, Perl doesn't know of any test_value() sub, and test_value is interpreted as string 'test_value'. In the second program, the definition of test_value() comes before the $a = test_value; line. Perl thinks test_value as sub call.

The technical term for isolated words like test_value that might be subs and might be strings depending on context, by the way, is bareword. Perl's handling of barewords can be confusing, and it can cause bug in program.

The bug is what we encountered in our first program, Remember that Perl won't look forward to find test_value(), so since it hasn't already seen test_value(), it assumes that you want a string. So if you use strict subs;, it will cause this program to die with an error:

Bareword "test_value" not allowed while "strict subs" in use at ./a6-strictsubs.pl line 3.

Solution to this error would be

  1. Use parentheses to make it clear you're calling a sub. If Perl sees $a = test_value();,

  2. Declare your sub before you first use it

    use strict; sub test_value; # Declares that there's a test_value() coming later ... my $a = test_value; # ...so Perl will know this line is okay. ....... sub test_value { return "test_passed"; }

  3. And If you mean to use it as a string, quote it.

So, This stricture makes Perl treat all barewords as syntax errors. A bareword is any bare name or identifier that has no other interpretation forced by context. (Context is often forced by a nearby keyword or token, or by predeclaration of the word in question.) So If you mean to use it as a string, quote it and If you mean to use it as a function call, predeclare it or use parentheses.

Barewords are dangerous because of this unpredictable behavior. use strict; (or use strict 'subs';) makes them predictable, because barewords that might cause strange behavior in the future will make your program die before they can wreak havoc

There's one place where it's OK to use barewords even when you've turned on strict subs: when you are assigning hash keys.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

Barewords in hash keys are always interpreted as strings, so there is no ambiguity.

use strict 'refs';

This generates a run-time error if you use symbolic references, intentionally or otherwise.

A value that is not a hard reference is then treated as a symbolic reference. That is, the reference is interpreted as a string representing the name of a global variable.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

use warnings;

This lexically scoped pragma permits flexible control over Perl's built-in warnings, both those emitted by the compiler as well as those from the run-time system.

From perldiag:

So the majority of warning messages from the classifications below, i.e., W, D, and S can be controlled using the warnings pragma.

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

I have listed some of warnings messages those occurs often below by classifications. For detailed info on them and others messages, refer to perldiag.

(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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
11

These two pragmas can automatically identify bugs in your code.

I always use this in my code:

use strict;
use warnings FATAL => 'all';

FATAL makes the code die on warnings, just like strict does.

For additional information, see: Get stricter with use warnings FATAL => 'all';

Also... The strictures, according to Seuss

toolic
  • 57,801
  • 17
  • 75
  • 117
10

There's a good thread on perlmonks about this question.

The basic reason obviously is that strict and warnings massively help you catch mistakes and aid debugging.

Borodin
  • 126,100
  • 9
  • 70
  • 144
moodywoody
  • 2,149
  • 1
  • 17
  • 21
2

Source: Different blogs

Use will export functions and variable names to the main namespace by calling modules import() function.

A pragma is a module which influences some aspect of the compile time or run time behavior of Perl. Pragmas give hints to the compiler.

Use warnings - Perl complains about variables used only once and improper conversions of strings into numbers. Trying to write to files that are not opened. It happens at compile time. It is used to control warnings.

Use strict - declare variables scope. It is used to set some kind of discipline in the script. If barewords are used in the code they are interpreted. All the variables should be given scope, like my, our or local.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rahul Reddy
  • 12,613
  • 10
  • 22
  • 21
1

The "use strict" directive tells Perl to do extra checking during the compilation of your code. Using this directive will save you time debugging your Perl code because it finds common coding bugs that you might overlook otherwise.

MikasaAckerman
  • 531
  • 5
  • 17
-1

Strict and warnings make sure your variables are not global.

It is much neater to be able to have variables unique for individual methods rather than having to keep track of each and every variable name.

$_, or no variable for certain functions, can also be useful to write more compact code quicker.

However, if you do not use strict and warnings, $_ becomes global!

-2
use strict;
use warnings;

Strict and warnings are the mode for the Perl program. It is allowing the user to enter the code more liberally and more than that, that Perl code will become to look formal and its coding standard will be effective.

warnings means same like -w in the Perl shebang line, so it will provide you the warnings generated by the Perl program. It will display in the terminal.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • What do you mean by *"Strict and warnings are the mode"*? And what do you mean by *"allowing the user to enter the code more liberally"*? Can you elaborate? Preferably by [editing your answer](https://stackoverflow.com/posts/38076212/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Apr 30 '21 at 20:42
  • dhana govindarajan seems to have left the building. – Peter Mortensen Apr 30 '21 at 20:45