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

perlbool.pod rev.1

Thread Previous | Thread Next
From:
Dan Kogai
Date:
June 30, 2003 01:42
Subject:
perlbool.pod rev.1
Message ID:
D13FFD2C-AAD6-11D7-86AF-000393AE4244@dan.co.jp
On Monday, June 30, 2003, at 04:33  PM, Tassilo von Parseval wrote:
>> 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.
>
> Yes, can't hurt.
> [...]
>
> Other than that, I like this draft. It's terse and straight to the 
> point
> which is what a user is most likely to find helpful.

Thank you for your support.  1st revision follows my signature.

Dan the Perl5 Porter

=head1 NAME

perlbool - semantics of boolean operations and conversions in Perl

=head1 SYNOPSIS

   $f = "0";          # false by definition
   $f = "";           # false by definition
   $f = 0;            # false by definition
   $f = 0.00;         # false because 0.00 == 0.
   $t =  \$a;         # always true
   $f = undef         # always false
   $t = 1;            # true
   $f = 10 - 10;      # equals 0 so false
   $t = "0.00";       # true! see below
   $f = "0.00" + 0    # numerically 0 so false
   $t = "0 but true"; # true, though 0 in numeric conversion
   @f = ();           # scalar @f is 0 so false
   @t = (0);          # scalar @t is 1 so true!
   %h = (0 => undef); # scalar %h is nonzero so %h is true
   delete $h{0};      # scalar %h is now 0 so %h is false

=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 numerical context
(because C<0x8134654> is hexadecimal for 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 C<scalar()>
thereof.  In other words, boolean values of arrays and hashes are
false when and only when they are empty.

C<@a = ()> is false but C<@a = (0)> and C<@a = ("")> are both 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;  # 1 if $a is true and 2 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 $t = NeverTrue->new("1 but false");
   printf "Boolean: %s\n", $t ? 't' : 'f';
   printf "String:  %s\n", $t . "";
   printf "Number:  %d\n", $t + 0;

=head1 AUTHOR

0th draft by Dan Kogai <dankogai@dan.co.jp>

Revision by Tassilo von Parseval
<tassilo.parseval@post.rwth-aachen.de> and Perl5 Porters
<perl5-porters@perl.org>

=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 Previous | 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