perlmeditation Xiong <blockquote>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. <p> <b>Hey!</b> I see a lot of discussion of warnings. <i>This tutorial is not about warnings.</i> It's not even advice to add <c>use strict;</c> 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 <i>bad</i> advice. </blockquote> <hr> <p>Newcomers to Perl often are told to add a line near the top of script or module:</p> <c> use strict; </c> <p> 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. <i>Now it blows up!</i></p> <readmore> <h2>Purpose of Strictures</h2> <p>We often <c>use strict;</c> 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 <b>unsafe constructs</b>. If <i>Perl is the Swiss Army Chainsaw of programming languages</i>, <c>use strict;</c> is the <i>chainguard</i> that keeps you from ripping off your own fingers. Use it for your own safety.</p> <p>Without strictures, your code didn't do what you expected; but it did do something: <i>the wrong thing</i>. Now it blows up and does nothing, which is <i>better</i> 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.</p> <h2>Strict Errors</h2> <p>There are (currently) three types of strictures: 'vars', 'subs', and 'refs'. When you write <c>use strict;</c> you are enforcing all three types.</p> <p>The general format of such errors is:</p> <c> (SOME_ERROR_TEXT) at (FILE) line (LINE). Execution of (FILE) aborted due to compilation errors. </c> <p> You may not understand the <c>SOME_ERROR_TEXT</c> but you should start looking for a problem in <c>FILE</c> at <c>LINE</c>.</p> <h3>strict 'vars'</h3> <p><b>Example:</b></p> <c> # Code: $x = 5; # no strict 'vars' print "$x\n"; # Output: Global symbol "$x" requires explicit package name at line 10. Global symbol "$x" requires explicit package name at line 11. Execution of aborted due to compilation errors. </c> <p><b>Why:</b> Perl itself does <i>not</i> require you to <b>declare</b> or initialize variables before you use them. The code is okay; but not under stricture.</p> <p><b>Solution:</b> Declare your variables:</p> <c> my $x; # declare first $x = 5; # strict okay print "$x\n"; </c> <p><b>Reason:</b> Avoid common typos such as:</p> <c> $newPig = 'Keisha'; # much, much later... print $Newpig; # prints nothing; why? </c> <h3>strict 'subs'</h3> <p><b>Example:</b></p> <c> # Code: my $subroutine = factorial; # no strict 'subs' print $subroutine->(7), "\n"; # Output: Bareword "factorial" not allowed while "strict subs" in use at line 13. Execution of aborted due to compilation errors. </c> <p><b>Why:</b> A <b>bareword</b>, 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.</p> <p><b>Solution:</b> If the bareword is the name of a subroutine, then prefix it with the appropriate <b>sigil</b> ( <c>&</c> ). You probably also want to take a reference to it ( <c>\</c> ):</p> <c> my $subroutine = \&factorial; # strict okay print $subroutine->(7), "\n"; </c> <p>You may have intended your bareword to mean something else instead: <c>$factorial</c>, <c>@factorial</c>, <c>%factorial</c>, or <c>'factorial'</c>. Fix it.</p> <p><b>Reason:</b> Don't make perl guess. The computer can't read your mind.</p> <h3>strict 'refs'</h3> <p><b>Example:</b></p> <c> # 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 line 18. </c> <p><b>Why:</b> When perl encounters <c>${ $pet }</c> it constructs the variable indicated; which is <c>${ 'dog' }</c> or just <c>$dog</c>. This is called a <b>symbolic reference</b>. Usually, you don't want to do this.</p> <p><b>Solution:</b> Avoid using the <i>identifier</i> of a variable as the <i>value</i> of another. You may find it useful to take a <b>hard reference</b> instead:</p> <c> our $dog; my $pet = \$dog; # hard reference ${ $pet } = 'Rover'; # strict okay print "$dog\n"; </c> <p><b>Reason:</b> [perldoc://perlref] says it best: <i>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.</i></p> <h2>The Art of Debugging</h2> <p>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.</p> <p>More advanced programmers try to write their code so, if it doesn't work properly, it will <b>die</b>: 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 <c>use strict;</c> which will catch many common coding mistakes.</p> <p>Professionals write <b>tests</b> for their <b>production code</b>; 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 [mod://Test::Simple]. I like to say that [mod://Test::More] is the most important Perl module of them all.</p> <p>When you first <c>use strict;</c> 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. <b>Stick with it.</b> Start with the first file name and line number given; check that line carefully. You may have to work backwards from there.</p> <p>Quite likely, an error that pops up under strictures is merely a typo; it may be due to your misunderstanding of Perl. Study <i>very carefully</i> the standard resources:</p> <ul> <li>[perldoc://perlintro]</li> <li>[perldoc://perlsyn]</li> <li>[perldoc://perldata]</li> <li>[perldoc://perlop]</li> <li>[perldoc://perlfunc]</li> <li>[perldoc://perlsub]</li> </ul> <p>You may want to look through the various [perldoc://perlfaq]s, too. [perldoc://perltoc] is a <i>long</i> list of all perldocs. You can get more help on the perldoc tool itself with [perldoc://perldoc].</p> <h2>no strict</h2> <p>At some point you will encounter code that turns strictures <i>off</i>, usually with one of the following lines:</p> <c> no strict 'vars'; no strict 'subs'; no strict 'refs'; </c> <p>You may be tempted to do the same; <b>don't</b>. 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.</p> <p>When you see a <c>no strict</c> line, you may assume that the following code doesn't play entirely straight. Please don't try to write code like that!</p> <h2>Demo</h2> <p>Here's a script that includes all the above demonstrations. Comment or uncomment lines to see what works with and without <c>use strict;</c></p> <c> # # = Copyright 2011 Xiong Changnian <> = # = 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__ </c> </readmore> <h2>Summary</h2> <p>The purpose of adding <c>use strict;</c> 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.</p> <h2>Thanks</h2> <ul> <li>[runrig] for the idea </li> </ul> <h2>Changes</h2> <p> Suggestions for improvement are welcome and will be incorporated. </p> <dl> <dt><i>22012-02-07:</i></dt> <dd>- new<br> </dd> </dl> <div class="pmsig"><div class="pmsig-704000"> <i>I'm not the guy you kill, I'm the guy you buy.</i> &mdash;Michael Clayton </div></div>