develooper Front page | perl.perl5.porters | Postings from June 2003

perlbool.pod

Thread Next
From:
Dan Kogai
Date:
June 29, 2003 05:13
Subject:
perlbool.pod
Message ID:
0256B036-AA2B-11D7-A340-000393AE4244@dan.co.jp
Porters,

Here is a draft of perlbool.pod.  Since we already have perlnumber.pod 
and overload.pm can handle bool differently from "" and 0+, I think 
boolean deserves a distinct pod if not a section.

Dan the "True" Man

=head1 NAME

perlbool - semantics of boolean operations and conversions in Perl

=head1 SYNOPSIS

   "0"          # false by definition
   ""           # false by definition
   0            # false by definition
   undef        # false; "" in string and 0 in number
   0.00         # false because 0.00 == 0.
   1            # true
   10 - 10      # equals 0 so false
   "0.00"       # true! see below
   "0.00" + 0   # numerically 0 so false
   "0 but true" # true, though 0 in numeric conversion
   \$a          # always true
   undef()      # false
   ()           # scalar () is 0 so false
   (0)          # scalar (0) is 1 so true!

=head1 DESCRIPTION

This document describes how Perl distinguish between true and false.

To perl, only the following values are false and everything else is
true.

=over

=item *

string C<""> (null string) and C<"0">

=item *

number C<0>

=back

Consider the above as axioms and any other "theorems" are reduced to
the axioms above.

=over

=item *

All references are true since it is neither string nor number.
This is unlike C which has null pointers.

=item *

When boolean values are needed, perl does not do any type coercion.
It just checks to see if the value matches  C<"">, C<"0">, or C<0>.

That is why C<"0.00"> is true while C<"0.00"+0> is false.  Though
"0.00" is numerically 0, it is "0.00" until numerical value is needed,
which is neither "" nor "0".

=back

=head2 References

Unlike C which has null pointers, perl's reference is always true
because in string context it would be something like
C<SCALAR(0x8134654)> in string and C<135480916>.

In practice perl does not waste time coercing references to strings
just to see if it is true because perl already knows this theorem

=head2 undef

C<undef()> is always false because it would evaluate to C<""> in
string context and C<0> in numerical context.

Like references already knows C<undef()> is always false so no
coercion takes place.

=head2 Boolean values of arrays and hashes

For boolean values of arrays and hashes, perl just uses scalar()
thereof.  In other words, boolean values of arrays and hashes are
false when and only when they are empty.

C<()> is false but C<(0)> and C<("")> are true.

=head2 0 but true

When you need a function that needs to return 0 in numerical value but
evaluates to true, use "0 but true" as the return value.

=head1 Boolean Context vs. Boolean Value

Though perl does not have explicit boolean value like C<t> or C<nil> in
LISP and ruby, perl does have boolean context.

   $a;         # void context
   $a+1        # scalar context
   push @a, $a # array context
   if ($a)     # boolean context

What is interesting is that perl's comparison operators return values
in scalar context; C<1> for true and C<undef> for false.

   not($a)+1;  # 2 if $a is true and 1 otherwise.

The lack of boolean value is no problem since boolean context exists.
See L</overload> for such cases that boolean context does differ from
scalar context.

=head1 Overload

Because perl does have boolean context, you can use L<overload> to
give your object a different idea from perl on what is true and false.
The following example make a scalar which is always false.

   package NeverTrue;
   use overload
     'bool'   => sub { 0 },
     '""'     => sub { my $self = shift; $$self },
     '0+'     => sub { my $self = shift; $$self },
     fallback => 1;
   sub new {
     my $class = ref $_[0] ? ref shift : shift;
     my $value = shift;
     return bless \$value => $class;
   };

   package main;
   my $f = NeverTrue->new("1 but false");
   printf "Boolean: %s\n", $f ? 't' : 'f';
   printf "String:  %s\n", $f . "";
   printf "Number:  %d\n", $f + 0;

=head1 AUTHOR

Dan Kogai <dankogai@dan.co.jp>

=head1 SEE ALSO

L<perldata>, L<perlop>, L<perlsyn>, L<perlnumber>, L<overload>

pp. 29-30 of "Programming Perl", 3rd Ed.
L<http://www.oreilly.com/catalog/pperl3/>


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About