Booleans in Perl

D

David Williams

Small question.
Why does PERL do the following

$a=FALSE;
$b=FALSE;
$c=($a && $b);
if($c){
echo "the expr evaluates to true";
}
else{
echo "the expr evaluates to false;
}

I always get "the expr evaluates to true";

if it is false && false, should it not be false?
My workaround is to use the eq operand
 
C

Charlton Wilbur

DW> Small question. Why does PERL do the following

DW> $a=FALSE; $b=FALSE; $c=($a && $b); if($c){ echo "the expr
DW> evaluates to true"; } else{ echo "the expr evaluates to false;
DW> }

DW> I always get "the expr evaluates to true";

use strict; use warnings;

You'll probably find out that that code doesn't do what you think it does.

(That is, if you're using Perl at all; the 'echo' function in there
makes me think you're using PHP, in which case you're in the wrong
newsgroup.)

DW> if it is false && false, should it not be false?

It's not false && false; it's the string "FALSE" and the string
"FALSE" - since non-empty strings evaluate to true, the whole
expression evaluates to true.

This will all be made clearer when you enable strictures and warnings.

Charlton
 
M

Mirco Wahab

David said:
Small question.
Why does PERL do the following

$a=FALSE;
$b=FALSE;
$c=($a && $b);
if($c){
echo "the expr evaluates to true";
}
else{
echo "the expr evaluates to false;
}

I always get "the expr evaluates to true";

if it is false && false, should it not be false?
My workaround is to use the eq operand

No, use some small code extension as shown and
proceed as you started:
==>

use strict;
use warnings;

package php;
sub echo { print @_ }

package bool;
sub true { return 1 }
sub false { return 0 }
use constant TRUE => true;
use constant FALSE => false;


package main; # <== your program starts here

my $a1 = bool::TRUE;
my $b1 = bool::FALSE;
my $c = ($a1 && $b1);

if( $c ){
php::echo "the expr evaluates to true"
}
else{
php::echo "the expr evaluates to false"
}

<==

I guess, perl6 will have the bool included.

Regards

M.
 
D

Dr.Ruud

Mirco Wahab schreef:
sub true { return 1 }
sub false { return 0 }
use constant TRUE => true;
use constant FALSE => false;

That looks like sub-stacking, but the compiler optimizes it:

$ perl -MO=Deparse -e'
sub true { return 1 }
sub false { return 0 }
use constant TRUE => true;
use constant FALSE => false;
$x = TRUE;
$y = FALSE
'
sub true {
return 1;
}
sub false {
return 0;
}
use constant ('TRUE', true());
use constant ('FALSE', false());
$x = 1;
$y = 0;
-e syntax OK



I write such more like:

$ perl -MO=Deparse -e'
use constant {FALSE => 0, TRUE => !0};
$x = TRUE;
$y = FALSE
'
use constant ({'FALSE', 0, 'TRUE', 1});
$x = 1;
$y = 0;
-e syntax OK
 
R

Randal L. Schwartz

Mirco> package bool;
Mirco> sub true { return 1 }
Mirco> sub false { return 0 }
Mirco> use constant TRUE => true;
Mirco> use constant FALSE => false;

This is almost never a good idea.

*Somebody* out there will write:

if (some_func() == TRUE) { ... }

and then get burned when some_func() returns 42 for true, not your
precious "1".

Remember, in Perl, there are many values of true and fewer but still many
values of false. Stop trying to force Perl's truth model into
a simple boolean space.

print "Just another Perl hacker,"; # the original
 
T

Tad McClellan

David Williams said:
Small question.
Why does PERL do the following

$a=FALSE;
$b=FALSE;
$c=($a && $b);
if($c){
echo "the expr evaluates to true";
}
else{
echo "the expr evaluates to false;
}

I always get "the expr evaluates to true";


Because the string 'FALSE' is a true value.

It is a true value because it is not one of the four values that
Perl (not PERL) considers false:

1) the number zero
2) the empty string
3) the undef value
4) a one character string where the character is the zero digit
if it is false && false, should it not be false?


FALSE && FALSE _is_ FALSE (which is a true value):

-------------------------------
#!/usr/bin/perl
use warnings;
#use strict;

my $a=FALSE;
my $b=FALSE;
my $c=($a && $b);

print "\$c is '$c'\n";
 
M

Mirco Wahab

Randal said:
Mirco> package bool;
Mirco> sub true { return 1 }
Mirco> sub false { return 0 }
Mirco> use constant TRUE => true;
Mirco> use constant FALSE => false;

This is almost never a good idea.

*Somebody* out there will write:

if (some_func() == TRUE) { ... }

and then get burned when some_func() returns 42 for true, not your
precious "1".

Oh, I forgot! You are, of course, right. I was blind-
folded, because in php, the following *would* work:

<going into php mode>

$c = 42;

if($c == TRUE) {
echo "$c is TRUE\n";
}
else {
echo "$c is FALSE\n";
}
</going into php mode>

and its TRUE/FALSE would be a magical
function to the left hand side.

What would be an appropriate idiomatic
approximation in Perl aside from the
obvious

if( $c ) {
print "$c is TRUE\n";
}

(or - why would't be any?)


Regards & Thanks

Mirco
 
M

Mirco Wahab

Dr.Ruud said:
I write such more like:

$ perl -MO=Deparse -e'
use constant {FALSE => 0, TRUE => !0};
$x = TRUE;
$y = FALSE
'
use constant ({'FALSE', 0, 'TRUE', 1});
$x = 1;
$y = 0;
-e syntax OK

OK, I tried to conjure up an overly compli-
cated 'php compatibility framework' ;-)

Yours is much more adequate, but the !0 would
(imho) always evaluate to 1 in Perl, so why
wouldn't one write it.


Regards & Thanks

Mirco
 
R

Randal L. Schwartz

Mirco> Yours is much more adequate, but the !0 would (imho) always evaluate to
Mirco> 1 in Perl, so why wouldn't one write it.

There's actually no promise of that. "Boolean-returning" operations are free
to return "any true" for true and "any false" for false, although in practice,
they return a predefined scalar (internally) of "true" and "false", which
look like "1" and "" respectively. Yes, "false" is not 0, but "".

print "Just another Perl hacker,"; # the original
 
J

Jürgen Exner

David said:
Small question.
Why does PERL do the following

$a=FALSE;
$b=FALSE;
$c=($a && $b);
if($c){
echo "the expr evaluates to true";
}
else{
echo "the expr evaluates to false;
}

I always get "the expr evaluates to true";

Interesting result. I am getting a bunch or compiler errors instead:

String found where operator expected at C:\tmp\t.pl line 6, near "echo "the
expr
evaluates to true""
(Do you need to predeclare echo?)
String found where operator expected at C:\tmp\t.pl line 9, at end of line
(Missing semicolon on previous line?)
syntax error at C:\tmp\t.pl line 6, near "echo "the expr evaluates to true""
Can't find string terminator '"' anywhere before EOF at C:\tmp\t.pl line 9.

Which version of Perl are you using?

jue
 
M

Mumia W.

[...]
package bool;
sub true { return 1 }
sub false { return 0 }
use constant TRUE => true;
use constant FALSE => false;
[...]

Why is the extra step of creating functions needed? "Use constant" does
this anyway behind the scenes, so you can just assign the values.

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

package main;
print bool::TRUE, "\n";
print bool::FALSE, "\n";
 
D

David Williams

Busted :)
I use php a lot and wrote echo instead of print.
I actually used print in my program.

So, what I get is that Perl does not really understand FALSE.

I guess my workaround is to use the eq operand.

Thanks everyone!


David Williams said:
Small question.
Why does PERL do the following
$a=FALSE;
$b=FALSE;
$c=($a && $b);
if($c){
echo "the expr evaluates to true";
}
else{
echo "the expr evaluates to false;
}
 
J

Jürgen Exner

So, what I get is that Perl does not really understand FALSE.

Well, sort of. It's just a string without any special significance.
I guess my workaround is to use the eq operand.

That's a poor workaround indeed.
Unfortunately you didn't tell us what your actual goal is. Perl offers a
large variety of boolean interpretation of data, no matter if strings or
numbers or even complex data structures, including functions to
differentiate between undefined data and data that is defined but will
evaluate to false.

One wild guess is that maybe you are using those values as flags to control
the execution flow of your program. While there may be cases where this
actually simplifies the code, in general it often indicates a not so optimal
design of the algorithm. Trying to police your code by using flags is about
as evil as goto's.

Also, where does that value 'FALSE' on the right side come from? In my
experience it is very, very rare that you are assigning a static boolean
value to a variable. Much more common is the case were an expression
determines the logical value.

Typical beginner's code:

if (errorcheck($input) == true) {
return false;
} else {
return true;
}

Once you explain that this can better be written as

return !errorcheck($input)

then the whole idea of using literal boolean values becomes a lot less
appealing.

jue
 
P

Peter J. Holzer

I use php a lot and wrote echo instead of print.
I actually used print in my program.

So, what I get is that Perl does not really understand FALSE.

Perl understands 'FALSE' as a string like every other string. It is not
a predefined constant.

Write

use strict;
use warnings;

at the start of all of your scripts to catch common errors.

I guess my workaround is to use the eq operand.

That's a bad idea. Use one of the values which are false, like 0, '', or
undef.

hp
 
C

Charlton Wilbur

DW> So, what I get is that Perl does not really understand FALSE.

DW> I guess my workaround is to use the eq operand.

Um, no. Perl understands false just fine; it's just a special
property of evaluating values in a Boolean way rather than a separate
type.

There are multiple false values. "" is false, as is 0. So if $foo is
"" and $bar is 0, if ($foo eq $bar) will be false. This is why your
workaround doesn't work in the general case.

It gets worse if you talk about truth, because everything that is not
false is true. "foo" is a true value, as is 1, as is "0 but true."

Your "workaround" is to understand how Boolean values work in Perl,
and to use them correctly. Perl is not PHP; if you want PHP, you know
where to find it.

Charlton
 
T

Tad McClellan

David Formosa (aka ? the Platypus) said:
On Fri, 20 Apr 2007 21:00:49 +0000 (UTC), David Williams

[...]
So, what I get is that Perl does not really understand FALSE.

Perl has a very simple model of the booleans, false is 0,'0' and '',
everything else is true.


everything else except undef is true. :)
 
M

Mark Clements

David said:
On Fri, 20 Apr 2007 21:00:49 +0000 (UTC), David Williams

[...]
So, what I get is that Perl does not really understand FALSE.

Perl has a very simple model of the booleans, false is 0,'0' and '',
everything else is true.
undef (among others) is false as well :)

F:\Documents and Settings\Mark3>perl -le "print ((undef)?'true':'false')"
false
 
A

anno4000

Randal L. Schwartz said:
Mirco> Yours is much more adequate, but the !0 would (imho) always evaluate to
Mirco> 1 in Perl, so why wouldn't one write it.

There's actually no promise of that. "Boolean-returning" operations are free
to return "any true" for true and "any false" for false, although in practice,
they return a predefined scalar (internally) of "true" and "false", which
look like "1" and "" respectively. Yes, "false" is not 0, but "".

Perl's standard "false" is both, really. It's "" as a string but 0
as a number.

perl -wle 'print (not 1) + 0'

doesn't warn like it would when "not 1" were just "". Devel::peek shows
the situation in detail.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top