Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
The following tutorial candidate is intended for rather raw newcomers. Some of the explanations may be a bit simplistic but I've tried to avoid giving too much detail. The newcomer already has much to absorb.

Hey! I see a lot of discussion of warnings. This tutorial is not about warnings. It's not even advice to add use strict; to a kiddie script; that's been given elsewhere, forcefully. I've made the assumption that the reader has already taken that advice. Now I want to show it wasn't bad advice.


Newcomers to Perl often are told to add a line near the top of script or module:

use strict;

Perhaps you've been so told and are now aghast to see your program halt unexpectedly with a new, possibly unsettling, error message. You may not feel you've moved forward. Before using strictures, your program just didn't work right. Now it blows up!

Purpose of Strictures

We often use strict; to prevent us from making stupid or careless mistakes. Perl is an extremely powerful and flexible language. You can do almost anything; but there are things you may not want to do. Sometimes we call these unsafe constructs. If Perl is the Swiss Army Chainsaw of programming languages, use strict; is the chainguard that keeps you from ripping off your own fingers. Use it for your own safety.

Without strictures, your code didn't do what you expected; but it did do something: the wrong thing. Now it blows up and does nothing, which is better than the wrong thing. Also, the error message tells you where you may have made a mistake and what seems to be wrong. This might be helpful and is a good place to start looking.

Strict Errors

There are (currently) three types of strictures: 'vars', 'subs', and 'refs'. When you write use strict; you are enforcing all three types.

The general format of such errors is:

(SOME_ERROR_TEXT) at (FILE) line (LINE). Execution of (FILE) aborted due to compilation errors.

You may not understand the SOME_ERROR_TEXT but you should start looking for a problem in FILE at LINE.

strict 'vars'

Example:

# Code: $x = 5; # no strict 'vars' print "$x\n"; # Output: Global symbol "$x" requires explicit package name at strict-demo.pl li +ne 10. Global symbol "$x" requires explicit package name at strict-demo.pl li +ne 11. Execution of strict-demo.pl aborted due to compilation errors.

Why: Perl itself does not require you to declare or initialize variables before you use them. The code is okay; but not under stricture.

Solution: Declare your variables:

my $x; # declare first $x = 5; # strict okay print "$x\n";

Reason: Avoid common typos such as:

$newPig = 'Keisha'; # much, much later... print $Newpig; # prints nothing; why?

strict 'subs'

Example:

# Code: my $subroutine = factorial; # no strict 'subs' print $subroutine->(7), "\n"; # Output: Bareword "factorial" not allowed while "strict subs" in use at strict- +demo.pl line 13. Execution of strict-demo.pl aborted due to compilation errors.

Why: A bareword, essentially, is anything that perl can't parse as something else. If you use a bareword then perl will try to interpret it; but perhaps not in the way you intended.

Solution: If the bareword is the name of a subroutine, then prefix it with the appropriate sigil ( & ). You probably also want to take a reference to it ( \ ):

my $subroutine = \&factorial; # strict okay print $subroutine->(7), "\n";

You may have intended your bareword to mean something else instead: $factorial, @factorial, %factorial, or 'factorial'. Fix it.

Reason: Don't make perl guess. The computer can't read your mind.

strict 'refs'

Example:

# Code: our $dog; my $pet = 'dog'; ${ $pet } = 'Rover'; # no strict 'refs' print "$dog\n"; # Output: Can't use string ("dog") as a SCALAR ref while "strict refs" in use at + strict-demo.pl line 18.

Why: When perl encounters ${ $pet } it constructs the variable indicated; which is ${ 'dog' } or just $dog. This is called a symbolic reference. Usually, you don't want to do this.

Solution: Avoid using the identifier of a variable as the value of another. You may find it useful to take a hard reference instead:

our $dog; my $pet = \$dog; # hard reference ${ $pet } = 'Rover'; # strict okay print "$dog\n";

Reason: perlref says it best: This is powerful, and slightly dangerous, in that it's possible to intend (with the utmost sincerity) to use a hard reference, and accidentally use a symbolic reference instead.

The Art of Debugging

Novices write code and run it; then they look at the output and try to decide if it's correct. If they're unsatisfied, they edit the code and run it again. Often they're confused because they don't know where things started to go wrong.

More advanced programmers try to write their code so, if it doesn't work properly, it will die: the program exits with a fatal error, displaying an error message including some suggestion of what went wrong and where. A first step is to use strict; which will catch many common coding mistakes.

Professionals write tests for their production code; these tests automatically exercise various aspects of the code. Testing is beyond the scope of this discussion but when you feel ready to step up, you are encouraged to study testing, starting with Test::Simple. I like to say that Test::More is the most important Perl module of them all.

When you first use strict; and encounter a fatal error, you may feel frustrated. Since you didn't intend to write one of these three types of unsafe constructs you may be wondering why you got the error you did. Often, what you thought you wrote is not what you really did write. Stick with it. Start with the first file name and line number given; check that line carefully. You may have to work backwards from there.

Quite likely, an error that pops up under strictures is merely a typo; it may be due to your misunderstanding of Perl. Study very carefully the standard resources:

You may want to look through the various perlfaqs, too. perltoc is a long list of all perldocs. You can get more help on the perldoc tool itself with perldoc.

no strict

At some point you will encounter code that turns strictures off, usually with one of the following lines:

no strict 'vars'; no strict 'subs'; no strict 'refs';

You may be tempted to do the same; don't. Yes, at some point you may become experienced enough to work without this safety net. But even experienced programmers avoid these unsafe constructs whenever possible. If they do disable strictures, they do so in the smallest possible scope.

When you see a no strict line, you may assume that the following code doesn't play entirely straight. Please don't try to write code like that!

Demo

Here's a script that includes all the above demonstrations. Comment or uncomment lines to see what works with and without use strict;

# strict-demo.pl # = Copyright 2011 Xiong Changnian <xiong@cpan.org> = # = Free Software = Artistic License 2.0 = NO WARRANTY = use strict; # comment out to avoid errors #--------------------------------------------------------------------- +-------# # Uncomment lines to force strict errors... # $x = 5; # no strict 'vars' # print "$x\n"; # my $subroutine = factorial; # no strict 'subs' # print $subroutine->(7), "\n"; # our $dog; # my $pet = 'dog'; # ${ $pet } = 'Rover'; # no strict 'refs' # print "$dog\n"; #--------------------------------------------------------------------- +-------# # Uncomment this whole section for a successful run... # my $x; # declare first # $x = 5; # strict okay # print "$x\n"; # my $subroutine = \&factorial; # strict okay # print $subroutine->(7), "\n"; # our $dog; # my $pet = \$dog; # hard reference # ${ $pet } = 'Rover'; # strict okay # print "$dog\n"; #--------------------------------------------------------------------- +-------# print "Done.\n"; sub factorial { my $in = shift; my $out = 1; for my $factor (2..$in) { $out *= $factor; }; return $out; }; __END__

Summary

The purpose of adding use strict; to the top of your scripts and modules is to force a fatal error instead of allowing your code to fail silently. It's your first and best friend in Perl.

Thanks

Changes

Suggestions for improvement are welcome and will be incorporated.

22012-02-07:
- new
I'm not the guy you kill, I'm the guy you buy. —Michael Clayton

In reply to RFC: Tutorial: use strict; now what!? by Xiong

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (4)
    As of 2014-07-24 04:48 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My favorite superfluous repetitious redundant duplicative phrase is:









      Results (157 votes), past polls