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


in reply to Default Hash Key

Just in case you have an 'XY' problem in your question, here's a common solution for this class of thing:

my %description = ( a => 'a vowel', b => 'a consonant' ); for my $choice (qw/a b c/){ print "$choice is ", $description{$choice} || "not in the alphabet. +", "\n"; }

Output:

a is a vowel b is a consonant c is not in the alphabet.

-- 
Human history becomes more and more a race between education and catastrophe. -- HG Wells

Replies are listed 'Best First'.
Re^2: Default Hash Key
by tford (Beadle) on May 02, 2008 at 04:32 UTC
    Wow thanks for the reply okol (and for the benefit of the doubt!) I really learned a lot from all the replies, but yours is nice and simple and probably about as fast as possible.

    I tried just a slight variation and I think it's going to work nicely.
    use strict; use warnings; my %description = ( a => 'a vowel', b => 'a consonant', default => 'not in the alphabet' ); for my $char (qw/a b c/) { my $d = $description{$char} || $description{default}; print("$char is $d\n"); }
    I still can't quite get my head around the way that the logical or works. I would think that it would only return 1 or 0, but evidently here it's returning the whole string back again.

    Anyway, thanks for all the help everybody. I did kinda post problem Y without getting into the specifics of problem X, but that was only because I thought X would bore everybody to tears!
      Just be careful about $description{foo} that evaluate to false:
      use strict; use warnings; my %description = ( a => 'a vowel', b => 'a consonant', 0 => '0', default => 'not in the alphabet' ); for my $char (qw/a b c 0/) { my $d = $description{$char} || $description{default}; print("$char is $d\n"); }
        Which is why god invented the '//' operator -- most definitely a better choice than '||' in this context.


        Evan Carroll
        I hack for the ladies.
        www.EvanCarroll.com
        Which is where the exists used in the first two original replies to the OP comes in handy...

        Because of things like this, I find myself using defined and exists a lot when writing code. It may be more verbose but better safe than sorry... I hope I'm not too much of a Captain Obvious :)
        That problem is avoided in Perl 5.10.0 with my $d = $description{$char} // $description{default}; # check for undefined rather than false As for getting one's head around the logical or, it's really quite simple: $a || $b || $c || ... yields the first value that is true (or false if none are). Perl didn't invent it; it's a common operator in many languages, dating back to Snobol, I think.
      tford:

      perldoc perlop yields:

      C-style Logical Or

      Binary "||" performs a short-circuit logical OR operation. That is, if the left operand is true, the right operand is not even evaluated. Scalar or list context propagates down to the right operand if it is evaluated.

      The "||" and "&&" operators return the last value evaluated (unlike C's "||" and "&&", which return 0 or 1). Thus, a reasonably portable way to find out the home directory might be:

      $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7] || die "You're homeless!\n";
      ...roboticus