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

What a well-done title :-) 1: I have noticed that if hash values are not defined that the hash definition can become askew: example:
%H = ( 'x' => 'y', 'y' => $undef_var, 'z' = 'a' );
then sometimes $H{y} might equal 'z' because the elements in the list simply shift up. 2: I tried to use a ternary operator to insure that each value of a hash had some value to avoid the above as follows:
#!/usr/bin/perl %p = ( 'a' => 'B', 'z' => defined($x) ? $x : '', 'c' => 'D'); use Data::Dumper; #warn Data::Dumper->Dump([\%p],['p']); warn $p{z};
But I am told that something is wrong with my warn line...

Replies are listed 'Best First'.
Re: Undefined Hash Values and Ternary Operators
by KM (Priest) on May 25, 2000 at 21:12 UTC
    I have never come across any random shifting in a hash like you state. If the keys value is undef, then it is undef. I have never seen Perl decide to suddenly change the values of keys.
    $a = undef; %H = ( 'x' => 'y', 'y' => $a, 'z' => 'a' ); for (1..10000) { print "FOO\n" if $H{x} ne 'y'; }

    Nothing prints. The ternary operator work how you are using it. You are likely getting a warning because you are calling warn(), with no conditional:

    warn "foo" unless defined($a);

    Is how you want to use that.

    Cheers,
    KM

RE: Undefined Hash Values and Ternary Operators
by mdillon (Priest) on May 25, 2000 at 21:19 UTC
    i'm not sure what the problem is. i tried your code above for initializing %H and $H{y} was never 'z'. the following code also works for me:
    my $undef_var = undef; my %hash; @hash{foo, bar, baz} = (1, $undef_var, 2); for (sort keys %hash) { printf "%s => %s\n", $_, defined $hash{$_} ? $hash{$_} : 'unde +f'; }
Re: Undefined Hash Values and Ternary Operators
by Adam (Vicar) on May 25, 2000 at 21:07 UTC
    I used the following script with no problems.
    #!/usr/bin/perl $x='y'; # comment this line out to test undef case. %p = ( 'a' => 'B', 'z' => defined($x) ? $x : 'n', 'c' => 'D'); print $p{z}
    (BTW:When you call warn it will generate a warning with the input you give it, so I'm not surprised by the warning you got. If you intended it as a test clause then you should say warn 'err' if( !defined($x) ); or something like that.)
    Oh, and yes... if you include an undef in an array it will get dropped, which is why your hash was acting funny.
      It has been said:
      Oh, and yes... if you include an undef in an array it will get dropped, which is why your hash was acting funny.
      This is not true. undef is a valid element of a list, and therefore an array.