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
.
C:\>perl -E "$x=undef; $y=$x // warn 'RHS evaluated'; say $y"
RHS evaluated at -e line 1.
1
C:\>perl -E "$x=''; $y=$x // warn 'RHS evaluated'; say $y"
C:\>perl -E "$x=0; $y=$x // warn 'RHS evaluated'; say $y"
0
C:\>perl -E "$x='true'; $y=$x // warn 'RHS evaluated'; say $y"
true
C:\>perl -E "$x=42; $y=$x // warn 'RHS evaluated'; say $y"
42
C:\>perl -V
Summary of my perl5 (revision 5 version 10 subversion 1) configuration
+:
Platform:
osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
uname='Win32 strawberryperl 5.10.1.3 #1 Thu Jul 29 10:08:11 2010 i
+386'
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und
+ef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITEC
+USTOMIZE -
DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -DPERL
+_MSVCRT_RE
ADFIX',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='3.4.5', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long lo
+ng', lseek
size=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\straw
+berry\c\li
b"'
libpth=C:\strawberry\c\lib
libs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
+ -ladvapi3
2 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinm
+m -lversio
n -lodbc32 -lodbccp32
perllibs= -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomd
+lg32 -ladv
api32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -l
+winmm -lve
rsion -lodbc32 -lodbccp32
libc=, so=dll, useshrplib=true, libperl=libperl510.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE
+" -L"C:\st
rawberry\c\lib"'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS
USE_LARGE_FILES USE_PERLIO USE_SITECUSTOMIZE
Built under MSWin32
Compiled at Jul 29 2010 10:20:18
@INC:
C:/strawberry/perl/lib
C:/strawberry/perl/site/lib
C:\strawberry\perl\vendor\lib
.
C:\>
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". ;-)