The defined-or operator, available since perl5.10, is an example of shortcut behaviour triggered on definedness and truth: If the left hand side is defined and true, leave it at that, otherwise evaluate the right hand side.
Are you sure? The defined-or operator in my perls test only for definedness, not for truth:
>perl -E '$x=undef; $y=$x // warn "RHS evaluated"; say $y'
RHS evaluated at -e line 1.
1
>perl -E '$x=""; $y=$x // warn "RHS evaluated"; say $y'
>perl -E '$x=0; $y=$x // warn "RHS evaluated"; say $y'
0
>perl -E '$x="true"; $y=$x // warn "RHS evaluated"; say $y'
true
>perl -E '$x=42; $y=$x // warn "RHS evaluated"; say $y'
42
>perl -V
Summary of my perl5 (revision 5 version 12 subversion 3) configuration
+:
Platform:
osname=linux, osvers=2.6.35.10, archname=x86_64-linux-thread-multi
uname='linux midas64 2.6.35.10 #2 smp thu jan 6 19:06:19 cst 2011
+x86_64 amd athlon(tm) ii x2 235e processor authenticamd gnulinux '
config_args='-de -Dprefix=/usr -Dvendorprefix=/usr -Dcccdlflags=-f
+PIC -Dinstallprefix=/usr -Dlibpth=/usr/local/lib64 /usr/lib64 /lib64
+-Doptimize=-O2 -fPIC -Dusethreads -Duseithreads -Dpager=/usr/bin/less
+ -isr -Dinc_version_list=5.12.2 5.12.1 5.12.0 5.10.1 5.10.0 5.8.8 5.8
+.7 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 -Darchname=x86_64-linux'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und
+ef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
+ -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_
+FILE_OFFSET_BITS=64',
optimize='-O2 -fPIC',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -f
+stack-protector -I/usr/local/include'
ccversion='', gccversion='4.5.2', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1
+6
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
+ lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -fstack-protector'
libpth=/usr/local/lib64 /usr/lib64 /lib64
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
libc=/lib64/libc-2.12.2.so, so=so, useshrplib=false, libperl=libpe
+rl.a
gnulibc_version='2.12.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -fPIC -fstack-protector
+'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_
+BIT_ALL
USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API
Built under linux
Compiled at Jan 26 2011 12:39:46
%ENV:
PERL_UNICODE="SDL"
@INC:
/usr/lib64/perl5/site_perl/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.12.3
/usr/lib64/perl5/vendor_perl/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.12.3
/usr/lib64/perl5/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/5.12.3
/usr/lib64/perl5/site_perl
/usr/lib64/perl5/vendor_perl
.
This is also consistent with the documentation of Perl 5.10.0:
Although it has no direct equivalent in C, Perl's // operator is related to its C-style or. In fact, it's exactly the same as ||, except that it tests the left hand side's definedness instead of its truth. Thus, $a // $b is similar to defined($a) || $b (except that it returns the value of $a rather than the value of defined($a)) and is exactly equivalent to defined($a) ? $a : $b.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] [d/l] [select] |
perl -E 'my $x = 0 ; say $x // "true" '
0
| [reply] [d/l] |
C:\>perl -E "my $x = 0 ; say $x // 'true'; my $y = 1; say $y // 'true'
+;$x = undef; my $a=$x // warn 'RHS evaluated'; say $a;"
0
1
RHS evaluated at -e line 1.
1
updated.
| [reply] [d/l] |
$x = undef;
my $a=($x // warn 'RHS evaluated');
say $a;
Since $x is not defined, // returns the right hand side, and the call to warn returns 1 (true) to report success.
| [reply] [d/l] [select] |