[Kc] Perl Noob

Eric Wilhelm scratchcomputing at gmail.com
Tue Sep 18 17:05:51 PDT 2007


# from Emmanuel Mejias
# on Tuesday 18 September 2007 16:35:

>> > > %env = ('USER',
>> > > 'SHELL',
>> > > 'HOSTNAME',
>> > > 'TERM',
>> > > 'HOME');
>> > >
>> > > foreach $key (sort(keys(%env))){
>> > > print "$env $ENV{$key}\n";
>> > > }

Your code has an undeclared variable, which would throw an error had you 
used strictures and warnings.

>Well, that didn't work. It just gave me a print out of USER TERM
>HOSTNAME and SHELL instead of actual 'username', 'xterm', some host,
>and /bin/bash. 

Not sure about that.  Hard to tell without seeing the code.

>right now the way i have it it just gives me...

>xterm
>emejias1

It should just be refusing to compile, but you did not use strict.

Your %env as-written is a hash (and has an odd number of elements, which 
would also trigger a warning had you used warnings.)  Thus, keys(%env) 
is only qw(USER HOSTNAME HOME) because 'SHELL' and 'TERM' are values.

You wanted to declare it as 'my @env = (...', which would be an array.  
The sigils can be a bit confusing at first, but once you understand 
them, they're quite readable.

>>>> I just recently started taking an online course in
>>>> Perl and I've also been using Perl by Example book as a reference.

Please tell me that book mentions strictures very early.  If not, throw 
it away and read `perldoc perlintro` and the definitive "Programming 
Perl" (possibly "Learning Perl", but really the camel is the way to 
go.) 

It would also be nice if you did not top-post to the mailing list.

  #!/usr/bin/perl

  use warnings;
  use strict;

  my @env_keys = qw(USER SHELL HOSTNAME TERM HOME);

  foreach my $key (@env_keys) {
    print "$key: $ENV{$key}\n";
  }

You will then notice that some of those are undefined and thus warn 
about the concatenation.  To deal with that, you'll want to check 
exists($ENV{$key}) or defined($ENV{$key}) -- they are subtly different.

Above all, please use strict and use warnings and declare your variables 
with 'my'.  Learning perl without those three things is altogether 
unpredictable and pretty unpleasant for everyone on the list as well.

If you're writing one-liners, you can also have these safety nets with 
the -M switch:

  $ perl -Mwarnings -Mstrict -e '%foo = qw( bar baz bort)'
  Global symbol "%foo" requires explicit package name at -e line 1.
  Execution of -e aborted due to compilation errors.

  $ perl -Mwarnings -Mstrict -e 'my %foo = qw( bar baz bort)'
  Odd number of elements in hash assignment at -e line 1.

Once you have good coding habits that run clean under strict and 
warnings, you can then spend your debugging time on the actual 
algorithmic mistakes rather than typos.

--Eric
-- 
software:  a hypothetical exercise which happens to compile.
---------------------------------------------------
    http://scratchcomputing.com
---------------------------------------------------


More information about the kc mailing list