Front page | perl.perl5.porters |
Postings from November 2011
[perl #103212] Split to list assignment in scalar context
From:
Zsban Ambrus
Date:
November 8, 2011 14:37
Subject:
[perl #103212] Split to list assignment in scalar context
Message ID:
rt-3.6.HEAD-31297-1320791825-1374.103212-75-0@perl.org
# New Ticket Created by Zsban Ambrus
# Please include the string: [perl #103212]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=103212 >
This is a bug report for perl from ambrus@math.bme.hu,
generated with the help of perlbug 1.39 running under perl 5.14.2.
-----------------------------------------------------------------
[Please describe your issue here]
This command gives an unexpected result:
$ perl -wE 'say scalar(($_x, $_y) = split "/", "one/two/three/four/five");'
3
One would naively think it should return 5, just like this command:
$ perl -wE 'say scalar((@_x) = split "/", "one/two/three/four/five");'
5
for the split returns a list of five strings and the list assignment returns
the number of scalars assigned.
The surprising behaviour of the first command is actually sort-of documented
in the perlfunc entry for split:
When assigning to a list, if LIMIT is omitted, or zero, Perl supplies a
LIMIT one larger than the number of variables in the list, to avoid
unnecessary work.
So in the first command, split("/", $s) is silently changed to split("/",
$s, 3) by the optimizer because it's assigned to a list of scalars, which
made split return three strings only. However, this documentation says this
is done only "to avoid unnecessary work", which I take as meaning this
shouldn't have an observable side effect.
I propose that you change split to use this implicit limit only when this
has no observable side effects, for example if the optimizer knows the list
assignment is always evaluated in void context.
This came up in the real world by the way, and I was utterly baffled by it
for a while: "http://www.perlmonks.com/?node_id=934401".
By the way, the bug still happens if you add an explicit limit of 0, eg.
$ perl -wE 'say scalar(($_x, $_y) = split "/", "one/two/three/four/five",
0);'
3
which is completely against what the docs say, as noted by core bug #3247
("https://rt.perl.org/rt3/Ticket/Display.html?id=3247"; that bug says it's
resolved, but it seems it's not).
Also, the bug is still present in perlblead as of a few weeks ago.
--
Ambrus
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=low
---
Site configuration information for perl 5.14.2:
Configured by ambrus at Sat Oct 1 19:00:08 CEST 2011.
Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
Platform:
osname=linux, osvers=2.6.37, archname=x86_64-linux
uname='linux king 2.6.37 #6 smp sun mar 13 20:15:05 cet 2011
x86_64 gnulinux '
config_args='-Dprefix=/usr/local/perl5.14
-Dman1dir=/usr/local/share/man/man1
-Dman3dir=/usr/local/share/man/man3
-Dsiteman1dir=/usr/local/share/man/man1
-Dsiteman3dir=/usr/local/share/man/man3 -d'
hint=recommended, useposix=true, d_sigaction=define
useithreads=undef, usemultiplicity=undef
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
ccversion='', gccversion='4.6.1', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
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 -L/usr/local/lib'
libpth=/usr/local/lib /lib/../lib64 /usr/lib/../lib64 /lib
/usr/lib /lib64 /usr/lib64 /usr/local/lib64
libs=-lnsl -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.11.2.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.11.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'
Locally applied patches:
---
@INC for perl 5.14.2:
/usr/local/perl5.14/lib/site_perl/5.14.2/x86_64-linux
/usr/local/perl5.14/lib/site_perl/5.14.2
/usr/local/perl5.14/lib/5.14.2/x86_64-linux
/usr/local/perl5.14/lib/5.14.2
/usr/local/perl5.14/lib/site_perl/5.14.1/x86_64-linux
/usr/local/perl5.14/lib/site_perl/5.14.1
/usr/local/perl5.14/lib/site_perl/5.14.0/x86_64-linux
/usr/local/perl5.14/lib/site_perl/5.14.0
/usr/local/perl5.14/lib/site_perl
.
---
Environment for perl 5.14.2:
HOME=/home/ambrus
LANG (unset)
LANGUAGE (unset)
LC_CTYPE=hu_HU
LD_LIBRARY_PATH=/home/ambrus/local/lib/
LOGDIR (unset)
PATH=/home/ambrus/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
PERL_BADLANG (unset)
SHELL=/usr/local/bin/bash
-
[perl #103212] Split to list assignment in scalar context
by Zsban Ambrus