In a message dated Mon, 15 Oct 2007, Doug McNutt writes:

At 18:20 -0700 10/15/07, Michael Barto wrote:
I think in the more newer languages, they have implemented true booleans. Perl 
is kind of old school.

use constant TRUE => 1;
use constant FALSE => 0;

Is a complete solution in perl 5.

Um, no, it's not:

  #!/usr/bin/perl

  use strict;
  use warnings;

  use constant TRUE => 1;
  use constant FALSE => 0;

  # Return a list of the sequence of even numbers from 0..$num
  # or false if we got an odd number
  sub evens_up_to {
      my $num = shift;

      if ($num % 2) {
          # didn't get an even!
          return FALSE;
      }

      return grep { not $_ % 2 } 0..$num;
  }

  for my $n (2, 4, 5) {
      if (my @nums = evens_up_to($n)) {
          print "$n is even: @nums\n";
      }
      else {
          print "$n is not even.\n";
      }
  }

Output is:
  2 is even: 0 2
  4 is even: 0 2 4
  5 is even: 0

Oops.  Now, change the return line:

  --- true.pl     2007-10-17 12:26:28.000000000 -0400
  +++ truenew.pl  2007-10-17 12:27:20.000000000 -0400
  @@ -13,5 +13,5 @@
         if ($num % 2) {
             # didn't get an even!
  -          return FALSE;
  +          return; # false via bare return
         }

Now you get:
  2 is even: 0 2
  4 is even: 0 2 4
  5 is not even.

Without resorting to tied handles or objects or other heavyweight chicanery, there is no single "FALSE" value you can define that will be false in all cases. Better to use bare return when it may be used like the above.

On the other hand, when a subroutine returns a scalar boolean, you probably *do* want to return 0 or undef, otherwise you can get into this nasty situation:

  my ($ready1, $ready2) = ($data1->is_ready, $data2->is_ready);

If is_ready() uses bare "return" fore false, then in the case where $data1 is not ready but $data2 is, $ready1 would be set to 1 and $ready2 would be undef, the exact opposite of what you'd expect, because $data1->is_ready would return the empty list so $data2->is_ready would squeeze over and fill the $ready1 spot. Nasty.

Moral of the story: there is no single false value in Perl 5, and trying to pretend there is one that is valid in all situations is asking for trouble.

As others have already noted, Perl 6 fixes this by both having a primitive boolean type and by having True and False roles that any value can mix in (so you can have a "0 but True" value or a "1 but False" one for example, or a false list containing elements, or a true list that's empty).

Trey

Reply via email to