[Melbourne-pm] just my opinion

Jacinta Richardson jarich at perltraining.com.au
Thu Sep 18 16:23:35 PDT 2008


Toby Corkindale wrote:

> What would you expect the output of the following script to be?
> 
> --------
> my %foo = (
>     undef => 'null',
>     foo   => 'bar',
>     qux   => 'qaaz'
> );
> print join(' ', @foo{qw(undef foo qux)}) . "\n";
> --------

Exactly what it is.  "null bar qaaz".  It doesn't make any sense to have an
undefined hash key (in fact Perl will complain under warnings if you try hard
enough (Use of uninitialized value in list assignment at - line 1.)).
Furthermore => is just like , *except* that it quotes any whole word to its
left.  Thus the first key there is 'undef' not a call to the function undef().
Use undef() if that's what you mean.

qw() is _quoted words_ *anything* you put inside them is treated just as a
sequence of characters (words) separated by spaces.  This includes variable
names, things which look like function calls, sequences of punctuation etc.

But okay, point taken.  If you put the characters "undef" in a place where Perl
will accept any bareword and treat it like a string, "undef" will also be
treated like a string.  This isn't any different from adding those letters to a
string yourself:

	print "It was undef";

In fact Perl gets this wrong with user defined subs as well.  For example:

my %opposites = (hello => 'goodbye', happy => 'sad', cold => 'warm');

print $opposites{hello};
print $opposites{awake};

sub hello {
	return "Awesome";
}

sub awake {
	return "hmmmmmm\n";
}

What gets printed?  "goodbye" of course (and an uninitialised warning if you
have warnings turned on).  Perl assumes that if you provide a bareword
consisting of only word characters for a hash lookup, that you intend that word
to be a key.  Always.

This is easily fixed by giving Perl more information.  Just as we should use
undef() instead of undef, we can use hello() or awake() up there to get the
desired effects.  "hello()" does not consist of only word characters, so Perl is
forced to look for a subroutine of that name.  (This is why $foo doesn't get
treated literally as well).

All the best,

	J

-- 
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | contact at perltraining.com.au |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |


More information about the Melbourne-pm mailing list