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

hi, im teaching myself perl here and everytime i post a question someone always says i should "use strict;" and "use warnings;" but evertime i do i always get loads of errors saying i need to declare stuff. when i dont have those "use" things on there everything works fine, my programs run the way i want them. so, how do i delcare variables and how do i know which ones use "my" and which ones dont? the ones that dont use "my" how do you declare them? are there any website that will explain it better to me? i just totally dont understand the variable thing. for example how do i properly declare the variables in this code:
#!usr/local/bin/perl use strict; use warnings; print ("Enter filename to search for punctuation characters: "); $path=<STDIN>; print ("\n"); open(DATA, "<$path") || die "Couldn't open $path for reading: $!\n"; while (<DATA>) { while (s/([\041-\057]|[\72-\100]|[\133-\140]|[\173-\176])(.*)/$2/) { my $count = $1; $wordHash{$count}++; } } %charnames = ( '?' => 'question mark', '.' => 'fullstop', ',' => 'comma', '(' => 'open bracket', ')' => 'close bracket', '-' => 'hyphen/minus', '$' => 'dollar', '=' => 'equals', '/' => 'forward slash', "\\" => 'backward slash', '|' => 'pipe', '!' => 'exclaimation', '"' => 'speech marks', '*' => 'asterisk', '£' => 'pound', '%' => 'percent', '^' => 'carrot', '&' => 'ampes and', '_' => 'underscore', '+' => 'plus', '{' => 'open curly bracket', '}' => 'close curly bracket', '[' => 'open square bracket', ']' => 'close square bracket', '~' => 'tilde', '#' => 'hash', '<' => 'less than', '>' => 'greater than', '@' => 'at', "'" => 'apostrophe', ':' => 'semi-colon', ';' => 'colon', ); while ( ($punctuation, $count) = each(%wordHash) ) { $wordArray[$i] = "$count\t$punctuation"; $i++; print ("$count\t$charnames{$punctuation}\n"); }
when i run this with the "use strict use warnings" i get this:
Global symbol "$path" requires explicit package name at punctuation.pl + line 6. Global symbol "$path" requires explicit package name at punctuation.pl + line 8. Global symbol "$path" requires explicit package name at punctuation.pl + line 8. Global symbol "%wordHash" requires explicit package name at punctuatio +n.pl line 14. Global symbol "%charnames" requires explicit package name at punctuati +on.pl line 17. Global symbol "$punctuation" requires explicit package name at punctua +tion.pl line 52. Global symbol "$count" requires explicit package name at punctuation.p +l line 52. Global symbol "%wordHash" requires explicit package name at punctuatio +n.pl line 52. Global symbol "@wordArray" requires explicit package name at punctuati +on.pl line 54. Global symbol "$i" requires explicit package name at punctuation.pl li +ne 54. Global symbol "$count" requires explicit package name at punctuation.p +l line 54. Global symbol "$punctuation" requires explicit package name at punctua +tion.pl line 54. Global symbol "$i" requires explicit package name at punctuation.pl li +ne 55. Global symbol "$count" requires explicit package name at punctuation.p +l line 56. Global symbol "%charnames" requires explicit package name at punctuati +on.pl line 56. Global symbol "$punctuation" requires explicit package name at punctua +tion.pl line 56. Execution of punctuation.pl aborted due to compilation errors.
what is an explicit package name? how do i delcare it? cheers.. hehe im such a noob!

2006-01-30 Retitled by g0n, as per Monastery guidelines
Original title: 'variables'

Replies are listed 'Best First'.
Re: Declaring variables under 'use strict'
by bobf (Monsignor) on Jan 30, 2006 at 04:09 UTC

    I applaud your desire to want to learn proper variable scoping. It may take a bit of reading and re-reading until it "clicks", but once it does it will be well worth it (meaning your code will be easier to read, debug, and maintain).

    To understand variable scoping, you need to understand the difference between lexical variables and global variables. There are many excellent resources to help you, including:

    • perldoc perlsub
    • perldoc perlfunc my
    • perldoc perlfunc our
    • perldoc perlfaq7 "What's the difference between dynamic and lexical (static) scoping? Between local() and my()?"
    • The PerlMonks Tutorials section, specifically the subsection on variables (my personal favorites include 'our' is not 'my' and Coping with Scoping, but they are all very good)

    Please take a look at some of those references. If you have specific questions, feel free to ask. Sorry for only posting links, but those references describe lexical scoping far better than I could and I'd only be repeating what they already say.

Re: Declaring variables under 'use strict'
by Cody Pendant (Prior) on Jan 30, 2006 at 05:40 UTC
    You don't actually need to use strict.

    It's just that if you don't, there are all kinds of annoying, easily-avoided errors which can get into your code. Using strict reduces the number of possible errors. One very simple mistake: you used "$count" twice in your program to count different things and didn't notice.

    while(<FILE>){ # do something $count++; # count lines in FILE } # somewhere else in your script sub count_digits { $string = shift(); $count = $string =~ tr/0-9/0-9/; return $count; }

    Now when you use $count, which one is it?

    Imagine you call someone for help because your car won't start. He says "You checked the fuel gauge, right? It has gas in the tank?" and you say "oh, I didn't check". He has the right to tell you to go and check and call him back, because that's so obvious. He might love fixing cars, and be prepared to do it for free, but he doesn't want to put gas in the tank for you, where's the fun in that?

    When you ask people for help here and you haven't used strict, you're like the guy who hasn't checked the gas. Using strict means your program has been automatically checked for the most obvious kind of error, leaving, hopefully, something more interesting.



    ($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
    =~y~b-v~a-z~s; print
Re: Declaring variables under 'use strict'
by davido (Cardinal) on Jan 30, 2006 at 06:14 UTC

    People telling you to use strict and use warnings are trying to save you time and frustration down the road. 'strict' enforces predeclaration of lexically scoped variables. Up to this point, you've been using package global variables. That's fine for a quick and dirty ten line script, but you'll quickly run out of gas on the superhighway if you never take advantage of lexical scoping.

    This isn't the simplest of concepts, but it doesn't have to start out as difficult as it seems. To begin with, before you use any variable, declare it like this:

    my $var; my %charnames; # etc...

    This will, in the most basic sense, ensure that you're complying with strictures. The next step will be to learn why you're doing this, and how it's helpful. I recommend that if you're going to teach yourself Perl, you let one of the pros help out. Beg, buy, borrow, or steal the Llama book: Learning Perl, published by O'Reilly & Associates. That's the best starting point I can think of. It's where most of us began. ...at least most of us who began learning Perl after the book was published. ;)


    Dave

Re: Declaring variables under 'use strict'
by spiritway (Vicar) on Jan 30, 2006 at 06:51 UTC

    Using 'use warnings;' and 'use strict;' will often give you tons of messages telling you that something's wrong. It's natural to want to avoid such discouraging messages, but these two instructions (called 'pragmas') will identify certain problems for you long before you get into trouble from them. They're something like a smoke alarm. You don't just take the batteries out of a smoke alarm when it sounds, you go find out what caused it to go off. Similarly, when you get messages from using strict and warnings, they are telling you that your code has problems. It's usually better to track down the problems, than to ignore them by removing the pragmas.

    Your error messages all refer to 'explicit package name', which is somewhat confusing. The problem is that you're using these variables without telling Perl anything about them - such as where you want them to exist. Perl allows you to do this, but as your programs get longer, this will cause problems. It is things like this that 'warn' and 'strict' help to avoid.

    For example, it is often convenient to use $i or $j as a counter or an index into an array. However, if you have several arrays, all using $i, you'll have problems if that same $i is visible and accessible to all the arrays. You need to tell Perl where each $i is allowed to be seen, or else you need to remember the value and location of all your variables, which becomes extremely difficult.

    The magic word for declaring variables to be lexically scoped (visible within a block of code, or a sub) is 'my'. It is a good idea to declare your variables close to where you're using them, and to also try to limit their scope as much as possible in order to avoid clashes with other variables with the same name. So, for example, you could do this:

    my $i=100; # Some code here... ... sub_1 { my $i; # This $i is undefined. It's not the same $i that was defined +outside the sub. # Code that uses $i ... } # $i now = 100, as before, since we're not in the sub. sub_2 { my $i = 4; # This $i = 4. print "$i\n"; # Prints 4. } # Once again, $i = 100.

    As your programs get longer, 'warnings' and 'strict' become more important in keeping you sane. Without them, it is very easy to introduce subtle, hard to find bugs that could take many hours to track down. It's a good idea to use these pragmas consistently, unless you have a very good reason to ignore them. And then it's still a good idea to disable them only for the smallest bit of code nesessary, and to enable them again when you're past that bit.

Re: Declaring variables under 'use strict'
by ysth (Canon) on Jan 30, 2006 at 08:39 UTC
    when i run this with the "use strict use warnings" i get this:
    Global symbol "$path" requires explicit package name at punctuation.pl + line 6.
    ...
    what is an explicit package name? how do i delcare it?
    Whenever perl gives you any warning or error message you are unsure of the meaning of, consult perldoc perldiag (or say use diagnostics;, which tries to do this for you).

    In this case, it says:

    (F) You've said "use strict vars", which indicates that all variables +must either be lexically scoped (using "my"), declared beforehand usi +ng "our", or explicitly qualified to say which package the global var +iable is in (using "::").
    which would at least have told you about "our", and explained the wording of the error message (which certainly isn't worded as helpfully as it could be).
A reply falls below the community's threshold of quality. You may see it by logging in.