Front page | perl.perl5.porters |
Postings from January 2008
Clarifying smart match behaviour in when( ... && ... )
Thread Next
From:
brian d foy
Date:
January 29, 2008 19:20
Subject:
Clarifying smart match behaviour in when( ... && ... )
Message ID:
290120082120310780%brian.d.foy@gmail.com
#!/usr/local/bin/perl5.10.0
=pod
I'm trying to figure out when() using smart-matching combined
with logical operators for the next edition of Learning Perl.
For a little background: perlsyn notes that there are exceptions
to smart matching in when():
* a subroutine call
* a regex using $_ by default (which is a smart match, btw)
* a regex expliclty bound to a variable (negated, even)
* an explicit comparison
* defined(), exists(), or eof()
* a negated expression (!, not)
* an xor
Right after that bit in perlsyn, it talks about &&.
If EXPR is ... && ... or ... and ... , the test is applied
recursively to both arguments. If both arguments pass the
test, then the argument is treated as boolean.
That last sentence is weird. If both arguments pass the test,
it's treated as boolean. What does that imply if one or both
don't pass the test? And, is "test" just "one of the previously
listed exceptions".
So, the example I was playing with wanted to check if a value was
in an array and also the key of a hash:
given( $foo ) {
when( @n && %n ) { ... }
}
Since neither of the arguments are one of the exceptions, I
expected both arguments to be treated as a smart match:
given( $foo ) {
when( $_ ~~ @n && $_ ~~ %n ) { ... }
}
Now, nothing in the docs say that should be the case, so before I
do too much work in going through the other odd situations I
found, I figure I'll check if it's a doc problem first or if I'm
being a lunkhead.
Here's what I think the docs are trying to say, and once we get
this right (which might mean correcting my thinking and
documenting it better) I can think about the rest of it:
If EXPR is ... && ... or ... and ..., and both of the
arguments are one of the listed exceptions, Perl treats both
arguments as booleans and performs no smart matching. If only
one of the arguments is one of the exceptions, Perl treats
that argument as a boolean and performs a smart match with
the other argument. If neither argument is one of the
exceptions, Perl performs a separate smart match with each
argument.
However, I don't know how to square the statement with a test in
t/op/switch.t. I think the test comment might be wrong. Should
there be a smart match that fails in the first when(), which is
why it moves onto the second? If so, the comment should say
something like "((1 == 1) && \"bar\") used smart match and fails
like it should".
# t/op/switch.t
{
my $ok = 1;
given("foo") {
when((1 == 1) && "bar") {
$ok = 0;
}
when((1 == 1) && $_ eq "foo") {
$ok = 2;
}
}
is($ok, 2, "((1 == 1) && \"bar\") not smartmatched");
}
I'll happily add some more tests once I know what the answers should
be. :)
Here's a program I was playing with, and the output I got that led me
to all of this.
=cut
use 5.010;
my @n = qw(0 Barney Wilma);
my %n = map { $_, 1 } @n;
$\ = "\n\t";
for( '', qw(0 1 Barney) )
{
my $n = $_;
say "\nProcessing [$n]...";
when( %n )
{ say "1. In \%n"; continue } # $_ ~~ %n
when( @n )
{ say "2. In \@n"; continue } # $_ ~~ @n
when( @n && %n )
{ say "3. @n && %n" } # $_ ~~ @n && $_ ~~ %n ???
}
__DATA__
Processing []...
Processing [0]...
1. In %n
2. In @n
Processing [1]...
Processing [Barney]...
1. In %n
2. In @n
--------
macbookpro_brian[2845]$ perl5.10.0 -V
Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
Platform:
osname=darwin, osvers=8.10.1, archname=darwin-2level
uname='darwin alexandria2-10.nyc.access.net 8.10.1 darwin kernel
version 8.10.1: wed may 23 16:33:00 pdt 2007;
root:xnu-792.22.5~1release_i386 i386 i386 '
config_args=''
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-common -DPERL_DARWIN -no-cpp-precomp
-fno-strict-aliasing -pipe -I/usr/local/include -I/opt/local/include',
optimize='-O3',
cppflags='-no-cpp-precomp -fno-common -DPERL_DARWIN -no-cpp-precomp
-fno-strict-aliasing -pipe -I/usr/local/include -I/opt/local/include'
ccversion='', gccversion='4.0.1 (Apple Computer, Inc. build 5363)',
gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags ='
-L/usr/local/lib -L/opt/local/lib'
libpth=/usr/local/lib /opt/local/lib /usr/lib
libs=-ldbm -ldl -lm -lc
perllibs=-ldl -lm -lc
libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false,
libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup
-L/usr/local/lib -L/opt/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP
USE_LARGE_FILES USE_PERLIO
Locally applied patches:
RC2
Built under darwin
Compiled at Dec 2 2007 12:18:58
@INC:
/usr/local/perls/perl-5.10.0-rc2/lib/5.10.0/darwin-2level
/usr/local/perls/perl-5.10.0-rc2/lib/5.10.0
/usr/local/perls/perl-5.10.0-rc2/lib/site_perl/5.10.0/darwin-2level
/usr/local/perls/perl-5.10.0-rc2/lib/site_perl/5.10.0
.
Thread Next
-
Clarifying smart match behaviour in when( ... && ... )
by brian d foy