Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

Alternate title: Read this if you want to cut your development time in half!

This is the brutally edited executive summary. The full version of this tutorial with extended discussion and examples is available at Use strict warnings and diagnostics or die

Perl has three pragmas specifically designed to make your life easier:

use strict;
use warnings;
use diagnostics;

The benefits of using these far outweigh the short learning curve. Once you get in the habit of using these pragmas you will find Perl isolates many problems automatically for you and can reduce development time by half or more (given that most of the time spent developing code is spent debugging).

So let's get down to it!

Bondage and discipline - use strict;

To activate the strict pragma we add the line use strict; just below the shebang line.
#!/usr/bin/perl
use strict;

By far the most useful thing use strict does is make you declare your variables. With use strict Perl complains if you try to use a variable that you have not previously declared.

$foo = 'bar'; 	# OK

use strict;
$foo = 'bar'; 	# Triggers an error

Fantastic you say, my simple program is now broken, and for what. For your sanity that's why. Consider this slightly longer (silly) example that counts down from ten then calls a sub liftoff. The liftoff sub is designed to count the number of liftoffs:

$count = 10;
while ($count > 0) {
    print "$count ";
    $count--;
    liftoff() if $count == 0;
}

sub liftoff {
    $count++; # count liftoffs
    print "This is liftoff $count\n";
}

Perfectly valid code, but if these two snippets were separated by other code the fact that this is an infinite loop might be harder to spot, especially without the print statements. The problem occurs because of the global variable $count, which is changed within the liftoff sub. As a result the while loop never exits, and repeatedly calls the liftoff sub. Whilst this is very simplified the fact is that common variables like $count, $line, $data, $i, $j etc are often used many times within a program. If we do not localise them to where they are used some very nasty bugs can arise. These bugs can often be hard to find.

You declare your variables under strict using the my keyword. The localisation (lexical scope) of a variable declared via my is most simply explained by example:

my $count = 10;
print "$count\n"; 	# $count is 10 here

{
    my $count = 5;
    print "$count\n";   # $count is 5 here 
}

print "$count\n"; 	# $count is 10 here again

In this example we have a $count with a wide scope and another *different* $count with a narrow scope. The narrow scope of one of the $count variables extends from the first opening curly before the my declaration to the corresponding closing curly. Talk about have your cake and eat it to!

For an extensive expert discussion of localising (scoping) variables see Coping with Scoping and Seven Useful Uses of Local by Mark-Jason Dominus.

Another reason to declare variables is tpyos. Consider this snippet of code:

use strict;
my $input_recieved = <STDIN>;
print $input_received;

See the error. Perl does. Because of the mis-spelling of received perl complains that we are using a variable we have not declared. This is very, very useful.

Baby help me please - the use warnings pragma

You activate the use warnings pragma with the "-w" flag like this:

#!/usr/bin/perl -w

Unlike strict when perl generates warnings it does not abort running your code, but it can fill up your screen :-) Here is a simple example of how warnings can *really* help:

$input_received = <STDIN>;
exit if $input_recieved =~ m/exit/i;
print "Looks like you want to continue!\n";

Three lines - what could be easier. We get some input from STDIN and exit if the user types exit. Otherwise we print something. When we run the code we find that regardless of what we type it prints. Why no exit?? If we had added the "-w" flag then perl would have told us:

Name "main::input_received" used only once: possible typo at test.pl line 3.
Name "main::input_recieved" used only once: possible typo at test.pl line 4.
test.pl syntax OK

So we have a syntax error, fix that and we are off and running. If we were using strict the code would not have run in the first place but that's another story. Typos like this can be hard for humans to spot but perl does it in a jiffy.

Use of a what in a where like how? - use diagnostics

When you first start to use warnings some of the messages appear quite cryptic. Don't worry, the "use diagnostics;" pragma has been designed to help. When this is active the warnings generated by "-w" are expanded greatly. All that happens is that Perl automatically looks up the warning in perlman:perldiag and gives you the full version. Save you from looking it up yourself! You will probably only need to use diagnostics for a few weeks as you soon become familiar with all the messages!

To finish off, here is another example:

#!/usr/bin/perl -w
use strict;
use diagnostics;

my @stuff = qw(1 2 3 4 5 6 7 8 9 10);
print "@stuff" unless $stuff[10] == 5;

If you run this code without warnings it runs OK, but does it? Sure it prints the array but there is a subtle problem. $stuff[10] does not exist! Perl is creating it for us on the fly. Use warnings catches this subtle trap and if we add the use diagnostics; pragma we will get a blow by blow description of our sins.

Use of uninitialized value in numeric eq (==) at test.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.

If you have reached here you are already well on the road to Perl nirvana. I hope you enjoy the journey.

tachyon

Credits

Lexicon, dragonchild, pmas, mpolo

In reply to Use strict warnings and diagnostics by tachyon

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 perusing the Monastery: (11)
    As of 2014-09-17 08:00 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (66 votes), past polls