http://www.perlmonks.org?node_id=275089

ironpaw has asked for the wisdom of the Perl Monks concerning the following question:

lo gain monks.
After reading a little about; use strict I am still confussed. Other than just declairing my variables about the place in a seemingly useless way can I get my scripts to run with this option and I fail to see the reason (I am sure there is a good one). I thought I'd try a different approach. Take the following horribly written script of mine (it works but pick it to bits if you like). What would be the most logical way to add Use Strict to this and why is that a benefit. If it makes it more readable how is that (how are you expecting to read a script)? I know I should use this option (I keep getting told to) but not really how or why. Does it improve speed? Does it prevent errors and if so how. I know this is a common question but maybe this way someone might answer it in a way we greenies understand (those who are learning without structure but want some like me). Thanks, I'm all for a good idea if I can understand and use it. Paw
use File::Find; $feeddir = "c:/orant8"; chdir("$feeddir"); find(\&wanted, "$feeddir"); sub wanted { m/TNSNAMES.ORA/i or return; Details($File::Find::name); } sub Details { $file = shift; open(CLEAN, "$file"); @cleanup = <CLEAN>; for ($i = 0; $i < scalar(@cleanup); $i++) { $cleanup[$i] =~ s/oldserv001/newserv001/ig; $cleanup[$i] =~ s/oldserv002/newserv002/ig; $cleanup[$i] =~ s/oldserv003/newserv003/ig; $cleanup[$i] =~ s/oldserv004/newserv004/ig; $cleanup[$i] =~ s/oldserv005/newserv005/ig; $cleanup[$i] =~ s/oldserv006/newserv006/ig; $cleanup[$i] =~ s/oldserv2001/newserv2001/ig; $cleanup[$i] =~ s/oldserv2006/newserv2002/ig; $cleanup[$i] =~ s/oldserv2008/newserv2003/ig; $cleanup[$i] =~ s/oldserv2009/newserv2004/ig; $cleanup[$i] =~ s/oldserv2010/newserv2005/ig; $cleanup[$i] =~ s/oldserv2011/newserv2006/ig; $cleanup[$i] =~ s/oldserv2012/newserv2007/ig; $new[$i]=$cleanup[$i]; } close CLEAN; } open(WRITE, "> $file"); print WRITE @new;

Edit by tye, title, add READMORE

Replies are listed 'Best First'.
Re: Use Strict
by dvergin (Monsignor) on Jul 17, 2003 at 02:50 UTC
    I'll take a shot at the "why" part with an example.

    Can you spot the error in the following snippet adapted from your code example?

    my @cleanup = ('an', 'array', 'of', 'words'); for (my $i = 0; $i < scalar(@c1eanup); $i++) { $cleanup[$i] =~ s/oldserv001/newserv001/ig; }
    If you look carefully you will see the flaw. But chances are strong that you would not notice it if you were staring at a whole page of code instead of just three lines. I've missed things much more obvious than this countless times.

    'use strict' would find this error immediately and tell you exactly were it was.

    Granted, a slip of the finger is not likely to produce this specific error. But many, many times I have had strict catch things I had looked at several times and missed. Once you become used to coding for strictness, you will find it an indespensable aid to accuracy in coding.

    The problem with not using strict is that usually the code will run but it will behave strangely and you will have little clue where to start looking for the problem.

    Think of strict as a way to say to Perl: "This is the name I intend to use for this variable. If I accidently spell it any other way, point out the exact line where I blundered."

    You may feel that strict is too much bother in short programs. My advice: use it in short programs anyway until it becomes second nature. That way when you are writing longer programs, you won't hit a sudden learning curve.

    Update: Another way strict-compliant coding often helps me can be illustrated by this snippet:

    ...lots of code here if ( $something ) { my $value = 'xyzzy'; ...more code here } ...lines and lines of more code
    Scoping: when I see that "my $value" inside the brackets of the 'if' block I know immediately that the $value has not been messed with before this 'if' block. I also know that it is not doing any mischief after this block. It is only present inside this block. That is an enormous benefit in figuring out what code (even your own) is doing.

    It can be a real frustration to be debugging or editing code and have no visual clue as to the scope of a variable. Can I safely mess with this variable? Did it have a value before we got here? Is something happening with it after this block that I need to be aware of? Who knows? ...unless the writer used strict and keep variable scope as narrow as possible.

    HTH,
    David

    ------------------------------------------------------------
    "Perl is a mess and that's good because the
    problem space is also a mess.
    " - Larry Wall

      'use strict' would find this error immediately and tell you exactly were it was.

      Okay I'll bite, what is wrong with the following?

      my @cleanup = ('an', 'array', 'of', 'words'); for (my $i = 0; $i < scalar(@c1eanup); $i++) { $cleanup[$i] =~ s/oldserv001/newserv001/ig; }

      I couldn't spot it and even plugging it into a script with -w and use strict gave no clues either. So if it works with strictures why is it wrong?

      Warnings and strictures are great during development, they are much like lint for C programs. However, it shouldn't be necessary for production code, and that is one thing that people forget. I would be wary of any code that didn't have use strict at the top, even if it was commented out, as the chances are it hasn't been run with strictures and as such, possibly not full tested.

      Warnings and strictures are there to help you spot glaring and subtle errors, which otherwise might show themselves in many weird and wonderful ways, and take a lot longer to figure out otherwise.

      --
      Barbie | Birmingham Perl Mongers | http://birmingham.pm.org/

        Notice the scalar statement. The array 'cleanup' was spelled with a 1 instead of a lowercase L. At first I thought you were right but then I realized I copied the code and didn't put use strict at the top. After doing so, strict caught the error :). What Perl are you using that it didn't?

        Lobster Aliens Are attacking the world!
Re: Use Strict
by Trimbach (Curate) on Jul 17, 2003 at 03:09 UTC
Re: Use Strict
by Cody Pendant (Prior) on Jul 17, 2003 at 06:19 UTC
    ironpaw, I had an example the other day which made my code completely broken because I didn't use strict.

    It's a beginner's error but I'll own up to it anyway.

    I have a subroutine which uses Date::Manip to find the day of the week for a series of dates. But when I ran it over my dates, everything was a Tuesday! I'd had a long day and this was driving me crazy.

    My mistake? My sub went like this:

    sub tell_me_the_day { $date = shift(); # a scalar, say 2003-07-01 ### chop the $date scalar up with a regex then push (@date_parts, $1,$2,$3); ### using Date::Manip; return &Date_DayOfWeek( $date_parts[1], $date_parts[2], $date_parts[3] ); }

    Now, I'm doing that a kludgey way, but the point is, I was sitting there thinking "It looks fine! What's wrong?" when strict would have told me what was wrong.

    Obviously, when this sub is run ten times, on ten $date scalars, it pushes more and more items onto the end @date_parts, but keeps sending the first three to Date::Manip.

    What I wanted was a new fresh @date_parts array every time, so I should have said "push (my @date_parts, $1,$2,$3);"



    “Every bit of code is either naturally related to the problem at hand, or else it's an accidental side effect of the fact that you happened to solve the problem using a digital computer.”
    M-J D