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

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

Hi, Perl noob here with a distinctly NoobFresh(TM) scented question.... ;-) Comment out "use strict;" in the below and it all works.... uncomment "use strict" and Perl starts giving me abuse about "Global symbol requires explicit package name". Help !
#!/usr/bin/perl use strict; %hash = ( ' Key1', ' Value1'); sub doStringTidy { my $string=shift; $string =lc($string); $string=~s/^\s+//; $string=~s/\s+$//; return $string; } sub doHashTidy { my $hash=shift; foreach my $k (keys %{hash}) { $kv=doStringTidy($k); $vv=doStringTidy($hash{$k}); delete $hash->{$k}; $hash{$kv} = $vv; } } doHashTidy(\%hash); foreach my $key ( keys %hash ) { print "key:$key, value:$hash{$key}\n"; }

Replies are listed 'Best First'.
Re: Strictly frustrating !
by marto (Cardinal) on Jul 26, 2013 at 14:49 UTC

    This isn't "abuse" by any means. When you have use strict; you have to declare variables. Your example above shows you're not being consistent in your approach. Some variables are declared, for example my $string=shift; while others aren't. Declare %hash, $kv and $vv before you use them. See also:

      hmmm... that seems to have fixed it in that example code, but when I paste those paras back into my main program it starts moaning again at those exact lines. I get the feeling I'm going to have to start again from a blank sheet of vi. ;-( Thanks for dropping by with your thoughts.

        If the line numbers and errors reported are the same then I can only suspect that you haven't saved the file. Is this the whole program? If not please pase the exact code and the output you get when running it.

      At a guess, I think the OP's use of the term "abuse" may be language-oriented, though it could simply be a manifestation of frustration. :-)
Re: Strictly frustrating !
by Crackers2 (Parson) on Jul 26, 2013 at 15:12 UTC

    You got some typos

    foreach my $k (keys %{hash}) {
    should probably be
    foreach my $k (keys %{$hash}) {
    and
    my $vv=doStringTidy($hash{$k}); delete $hash->{$k}; $hash{$kv} = $vv;
    should be
    my $vv=doStringTidy($hash->{$k}); delete $hash->{$k}; $hash->{$kv} = $vv;
    Since $hash is a hashref.
      This looks like the problem to me as well. (I'm a little late getting my answer in.) This version of your original code works for me:
      #!/usr/bin/perl use strict; my %hash = ( ' Key1', ' Value1'); sub doStringTidy { my $string=shift; my $string =lc($string); $string=~s/^\s+//; $string=~s/\s+$//; return $string; } sub doHashTidy { my $hash=shift; foreach my $k (keys %{$hash}) { my $kv=doStringTidy($k); my $vv=doStringTidy($hash->{$k}); delete $hash->{$k}; $hash->{$kv} = $vv; } } doHashTidy(\%hash); foreach my $key ( keys %hash ) { print "key:$key, value:$hash{$key}\n"; }
      which provides the following output:
      key:key1, value:value1
Re: Strictly frustrating !
by marinersk (Priest) on Jul 26, 2013 at 16:00 UTC
    Summary of Problem: You don't seem to understand what strict does.

    The use of strict has many, many advantages, but the main one for new Perl programmers is it helps you catch typos in your variable names (scalars and arrays for sure, though it can occasionally be less helpful in this regard with hashes). I ran your code as originally supplied and got the following list of errors:

    C:\Steve\Dev\PerlMonks\P-2013-07-26@0942-Strict>perl testStrict.pl Global symbol "%hash" requires explicit package name at testStrict.pl +line 3. Global symbol "%hash" requires explicit package name at testStrict.pl +line 13. Global symbol "$kv" requires explicit package name at testStrict.pl li +ne 14. Global symbol "$vv" requires explicit package name at testStrict.pl li +ne 15. Global symbol "%hash" requires explicit package name at testStrict.pl +line 15. Global symbol "%hash" requires explicit package name at testStrict.pl +line 17. Global symbol "$kv" requires explicit package name at testStrict.pl li +ne 17. Global symbol "$vv" requires explicit package name at testStrict.pl li +ne 17. Global symbol "%hash" requires explicit package name at testStrict.pl +line 20. Global symbol "%hash" requires explicit package name at testStrict.pl +line 21. Global symbol "%hash" requires explicit package name at testStrict.pl +line 23. Execution of testStrict.pl aborted due to compilation errors.

    The first error says it doesn't know what %hash is in line 3:

    %hash = ( ' Key1', ' Value1');

    The reason is because without strict, Perl will happily create %hash for you dynamically. Once you indicate you wish to use strict;, Perl surrenders this behavior and expects you to define %hash yourself.

    A friend of mine once indicated he didn't use strict; because he wanted to simplify things. He created some of the most difficult Perl scripts to debug because of it. Trust me: use strict; saves you a metric ton of work more than it costs you to use it.

    So back to the problem. You need to manually define %hash.

    This is done, in this case, by using the keyword my. So change the line thusly:

    %hash = ( ' Key1', ' Value1'); my %hash = ( ' Key1', ' Value1');
    When I run this, I get:
    C:\Steve\Dev\PerlMonks\P-2013-07-26@0942-Strict>perl testStrict2.pl Global symbol "$kv" requires explicit package name at testStrict2.pl l +ine 14. Global symbol "$vv" requires explicit package name at testStrict2.pl l +ine 15. Global symbol "$kv" requires explicit package name at testStrict2.pl l +ine 17. Global symbol "$vv" requires explicit package name at testStrict2.pl l +ine 17. Execution of testStrict2.pl aborted due to compilation errors.

    With a single keyword, we've eliminated over half the errors.

    I will bet you can deduce the remainder of your corrective actions from this (key hints exist in other responses in this thread).

    Have fun!
    (And don't be afraid to ask more questions. Initially, most answers lead to more questions, which is why experience is something you can't buy, you have to earn -- by doing, as you are. Keep up the good work!)

      Thank you marinersk. I think with the help of the various hints here, I've managed to get it working. Thank you all.
        I know strict can be frustrating when starting out however if you get used to coding with strict in mind you will save so much time troubleshooting larger scripts and it helps with making your scripts more readable to others.

        Sparky
        FMTEYEWTK
Re: Strictly frustrating !
by mtmcc (Hermit) on Jul 26, 2013 at 14:55 UTC
    This meditation is also helpful.