Return values of boolean operators

T

Tim McDaniel

OK, which man page is it that has documentation of the return values
of boolean operators? 1 and '', but I dimly recall that there's
something special about the particular '' returned for false, that it
avoids ... um, some kind of warning if ... something ...
 
P

Peter Makholm

OK, which man page is it that has documentation of the return values
of boolean operators? 1 and '', but I dimly recall that there's
something special about the particular '' returned for false, that it
avoids ... um, some kind of warning if ... something ...

See the perlop man page under the heading "Relational Operators".

Basically it returns a dualvar, not quite unlike what is returned by

Scalar::Util::dualvar(0,"")

//Makholm
 
$

$Bill

OK, which man page is it that has documentation of the return values
of boolean operators? 1 and '', but I dimly recall that there's
something special about the particular '' returned for false, that it
avoids ... um, some kind of warning if ... something ...

perlsyn man page:

Truth and Falsehood
The number 0, the strings '0' and '', the empty list "()", and "undef" are
all false in a boolean context. All other values are true. Negation of a
true value by "!" or "not" returns a special false value. When evaluated as
a string it is treated as '', but as a number, it is treated as 0.

perldata man page:

Scalar Values
A scalar value is interpreted as TRUE in the Boolean sense if it is not the
null string or the number 0 (or its string equivalent, "0"). The Boolean
context is just a special kind of scalar context where no conversion to a
string or a number is ever performed.

perlfunc man page:

defined EXPR
defined
Returns a Boolean value telling whether EXPR has a value other than the
undefined value "undef". If EXPR is not present, $_ is checked.

Many operations return "undef" to indicate failure, end of file, system
error, uninitialized variable, and other exceptional conditions. This
function allows you to distinguish "undef" from other values. (A simple
Boolean test will not distinguish among "undef", zero, the empty string,
and "0", which are all equally false.) Note that since "undef" is a
valid scalar, its presence doesn't *necessarily* indicate an exceptional
condition: "pop" returns "undef" when its argument is an empty array,
*or* when the element to return happens to be "undef".

(fcntl)
...
You don't have to check for "defined" on the return from "fcntl". Like
"ioctl", it maps a 0 return from the system call into "0 but true" in
Perl. This string is true in boolean context and 0 in numeric context.
It is also exempt from the normal -w warnings on improper numeric
conversions.

perlglossary man page:

Boolean
A value that is either "true" or "false".

Boolean context
A special kind of "scalar context" used in conditionals to decide
whether the "scalar value" returned by an expression is "true" or
"false". Does not evaluate as either a string or a number. See
"context".
 
T

Tim McDaniel

See the perlop man page under the heading "Relational Operators".

I'm afraid that's not so in the Perl 5.14.2 installation. That
section has only

Relational Operators
Binary "<" returns true if the left argument is numerically
less than the right argument.

Binary ">" returns true if the left argument is numerically
greater than the right argument.

Binary "<=" returns true if the left argument is numerically
less than or equal to the right argument.

Binary ">=" returns true if the left argument is numerically
greater than or equal to the right argument.

Binary "lt" returns true if the left argument is stringwise
less than the right argument.

Binary "gt" returns true if the left argument is stringwise
greater than the right argument.

Binary "le" returns true if the left argument is stringwise
less than or equal to the right argument.

Binary "ge" returns true if the left argument is stringwise
greater than or equal to the right argument.
 
T

Tim McDaniel

perlsyn man page:

Truth and Falsehood
The number 0, the strings '0' and '', the empty list "()", and
"undef" are all false in a boolean context. All other values are
true. Negation of a true value by "!" or "not" returns a special
false value. When evaluated as a string it is treated as '', but
as a number, it is treated as 0.

Aha! That matches the text in "man perlsyn" in Perl 5.14.2. (Silly
me, thinking that true and false would be documented in perldata or
perlop, and not in the syntax page.)
perldata man page: ....
perlfunc man page: ....
perlglossary man page:

Useful pointers to info on true and false in Perl, but they don't say
what the operators *return*, jsut what is *accepted* as true/false.
 
$

$Bill

Aha! That matches the text in "man perlsyn" in Perl 5.14.2. (Silly me, thinking that true and false would be documented in perldata or perlop, and not in the syntax page.)
It's easier to find stuff if you combine all the man pages into a single text doc
and use Vim (or your favorite editor) to search for what you're looking for.

I'll include my 10 year old version here since it's < 200 lines - may need some
updating - hope that doesn't bother anyone. To search for a
function (sysread for eg) in the output file using Vim I
just use
/^ sysread
since they're always 4 columns in in the output file.

#!perl -sw --

use strict;
use Config;
use Pod::Text;
use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1;

# copyright 2001 $Bill Luebkert - you may use/modify freely
#
# make perl manual from pods into single text file
# Usage: perl perlman.pl >perl.man (or perlman.txt or whatever)
#
# Ignore any errors you may get from pod2text conversion module
#

$| = 1;

use vars qw($h $help $s $d);

my $pod_dir = "$Config{archlib}/pod"; # directory where core pod files are
$pod_dir = "$Config{archlibexp}/pods" if $] > 5.008;

my @extra_pods = (); # other pod file dirs to check - add your own
# push @extra_pods, "$Config{sitelib}/pod" if $] <= 5.008;
# push @extra_pods, "$Config{archlibexp}/pods" if $] > 5.008;

print <<EOD and exit 0 if $h or $help;

Combines all of the Perl man pages into a single file for searching
and reference. Should generate a lot of format errors.

Usage: $0 [-s] [<pod-dir>] [>perl.man]
-s silent (no progress lines)
pod-dir optional directory in which to find pod files

EOD

# core sections and ones to skip
my @sections = (); # built automatically in main if empty (section order)
my %sections = (); # built automatically in main if empty (section hdrs)
my %do_not_want = (); # Ones I don't want in my manual

# get core sections (not language or platform specific)
get_sections () if not @sections;

# add windows specific section
push @sections, 'perlwin32';
$sections{'perlwin32'} = 'Perl notes for Windows';

main ();

exit 0;

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub main {

my %pods;

opendir DIR, $pod_dir or die "Error on opendir $pod_dir: $!\n";
while (defined ($_ = readdir DIR)) {
next if !/\.pod$/;
s/\.pod$//i;
$pods{$_} = 1;
}
closedir DIR;

# get the core sections in order

foreach (@sections) {

my $section = $_;
my $sect_hdr = $sections{$section};

if (exists $do_not_want{$section}) {
print STDERR "Skipping $section Section\n" if !$s;
next;
}
print STDERR "Doing $section '$sect_hdr'\n" if !$s;

if (not exists $pods{$section}) {
print STDERR "$section section missing\n";
next;
}

printf "\n%-20.20s %s\n\n", $section, $sect_hdr;
pod2text ("-80", "$pod_dir/$section.pod");
delete $pods{$section};
}

if (0) { # commented out for now

# handle any extra sections found that weren't in my list

print STDERR "Doing extra section\n" if !$s;
foreach (sort keys %pods) {

if (exists $do_not_want{$_}) {
print STDERR "Skipping $_ Section\n" if !$s;
next;
}
print STDERR "Doing $_ Section\n" if !$s;
print "$_ Section\n\n";
pod2text ("-80", "$pod_dir/$_.pod");
}

# handle any extra directories of pods

print STDERR "Doing extra directories requested\n" if !$s;
foreach my $dir (@extra_pods) {

opendir DIR, $dir or die "Error on opendir $dir: $!\n";
while (defined ($_ = readdir DIR)) {

next if !/\.pod/;
s/\.pod$//io;
if (exists $do_not_want{$_}) {
print STDERR "Skipping $_ $dir\n" if !$s;
next;
}
print STDERR "Doing $_ extra section\n" if !$s;
print "$_ section\n\n";
pod2text ("-80", "$dir/$_.pod");
}
closedir DIR;
}

} # if 0

}

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

sub get_sections {

open IN, "$pod_dir/perl.pod" or die "open $pod_dir/perl.pod: $! ($^E)";
my $lines;
{ undef $/; $lines = <IN>; }
close IN;

$lines =~ s/^.*?=head2 Overview>*?\n//is;
$lines =~ s/\s*=head2 Language-Specific.*$//is;
print (Data::Dumper->Dump([$lines], [qw($lines)])) if $d;
foreach (split /\n/, $lines) {
next if /^\s*$/;
next if /^\s*=head2/;
my @F = split ' ', $_, 2;
push @sections, $F[0];
$sections{$F[0]} = $F[1];
}
print (Data::Dumper->Dump([\@sections], [qw(@sections)])) if $d;
print (Data::Dumper->Dump([\%sections], [qw(%sections)])) if $d;

}

__END__
 
P

Peter Makholm

I'm afraid that's not so in the Perl 5.14.2 installation. That
section has only

No, it seems to have been added in the documentation for 5.16:

Perl operators that return true or false generally return values that
can be safely used as numbers. For example, the relational operators
in this section and the equality operators in the next one return 1
for true and a special version of the defined empty string, "" , which
counts as a zero but is exempt from warnings about improper numeric
conversions, just as "0 but true" is.

//Makholm
 
R

Rainer Weikusat

Ben Morrow said:
Exactly the same, in fact, except for PL_sv_no (the internal name of the
standard 'false' value) being a readonly constant. That means that this

my $x = \!1;
$$x = 1;

will fail, whereas a ref to a dualvar can be modified. They are
otherwise identical, as you can see with Devel::peek.

At least for me, they're not. Dumping a false value results in

SV = PVNV(0x83c2188) at 0x83fb448
REFCNT = 1
FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x83fe968 ""\0
CUR = 0
LEN = 4

while a dualvar constructed in this kind yields

SV = PVMG(0x840fad8) at 0x8400868
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 0
NV = 0
PV = 0x83d6618 ""\0
CUR = 0
LEN = 4
 
R

Rainer Weikusat

Peter Makholm said:
No, it seems to have been added in the documentation for 5.16:

Perl operators that return true or false generally return values that
can be safely used as numbers. For example, the relational operators
in this section and the equality operators in the next one return 1
for true and a special version of the defined empty string, "" , which
counts as a zero but is exempt from warnings about improper numeric
conversions, just as "0 but true" is.

The reason for this being that this 'special version of the defined
empty string' (how did the regretful lapse of implying that 'the
undefined value' is 'an empty string' instead of 'an undefined pointer'
creep in here?) is what results from converting an empty string to a
number. These "Type conversion detected !!1 Run for your life
lest the snark^WGosling will eat you !!2" are presumably latter-day
additions to the code performing type conversions.
 
R

Rainer Weikusat

Rainer Weikusat said:
These "Type conversion detected !!1 Run for your life
lest the snark^WGosling will eat you !!2" are presumably latter-day
additions to the code performing type conversions.

Demonstration of that (5.10.1):

[rw@sable]~#perl -w <<'TT'
$s = "";
$n = $s + 2;
$n = $s + 3;
TT
Argument "" isn't numeric in addition (+) at - line 2.

This warns only once because $s has already been converted when
executeing the second addition.
 
R

Rainer Weikusat

Ben Morrow said:
[...]
At least for me, they're not. Dumping a false value results in

SV = PVNV(0x83c2188) at 0x83fb448
REFCNT = 1
FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x83fe968 ""\0
CUR = 0
LEN = 4

That's not PL_sv_no: sv_no is immortal, so it has a very high refcount,
and readonly. It's probably a copy of sv_no: it's got an empty string
part, and zero IV and NV parts.
Yes.
while a dualvar constructed in this kind yields

SV = PVMG(0x840fad8) at 0x8400868

I've no idea how you got a PVMG out of dualvar, but I think you must
have assigned the result to a variable which had already been used for
something else. The normal return value of dualvar is a PVNV.

This turned out to be a side-effect of using the Perl debugger
interactively.
This SV is otherwise identical to the one above: it isn't NOK yet, but
that's just because it hasn't been evaluated in a NV context. The
difference between IOK and NOK is not visible from Perl.

That would make it a SV which is equivalent for certain purposes but not
for others (trivially, SvNOK will indicate 'it is one' for the 'false'
value but not for the dualvar, at least according to the documentation).
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top