4

I am doing the following, but it is not working properly:

    my $enabled = $hash && 
                  $hash->{'key'} && 
                  $hash->{'key'}->{'enabled'} && 
                  $hash->{'key'}->{'active'};

Is this an acceptable way to assign a boolean value to a scalar variable? My code is misbehaving in strange ways, as it is, and I believe it is because of this assignment. I have validated that the individual values exist for all of these keys and are set to a value.

P.S. Sorry for being a noob! I googled for ~10 minutes and couldn't find the answer anywhere.

heypano
  • 185
  • 1
  • 8

1 Answers1

7

The Perl boolean operators like &&, ||, and, or don't return a boolean value, they return the value of one of their arguments:

say 2 && 3;

outputs 3.

You can force it to a boolean with the double negation trick:

say !!(2 && 3);
# or
say not not 2 && 3;

outputs 1.

amon
  • 57,091
  • 2
  • 89
  • 149
  • But isn't 3 considered true since I read somewhere that in a numeric sense 0 == false and the rest > 0 equals true. The double negation trick is only nessercary for style? – Haagenti Jun 26 '13 at 19:54
  • 2
    @Grimm Yes, `3` is a true value. However, Squawk's code will assign the value of `$hash->{key}->{active}`, if all the other predicates are true. This may be the source of his problem, e.g. if it is printed out, concatenated or used for further calculations. E.g. strings are true, but usually numerically zero. If double negation fixes it, the problem lies here. (Note: all numbers `!= 0` are true, including negatives) – amon Jun 26 '13 at 19:57
  • 1
    Thanks a lot! :) Just to clarify, if $hash->{'key'} exists and is not one of the perl false values it will return something that is true, whereas if it doesn't exist, or if it does and is one of the perl false values it will return false The above expression will return the last value evaluated, which, for the intents and purposes serves the function of && and || in the correct manner. Is that correct? Thanks again! – heypano Jun 26 '13 at 21:14
  • @Squawk Jup, I think you got it. If any of the predicates in your `&&`-sequence is false, you will assign that value (whether it is zero, the empty string, `undef`, or an overloaded object). If a hash entry does not exist, you'll get the `undef` value. If all other parts are true, you'll assign the last value. – amon Jun 27 '13 at 07:22