Closed p5pRT closed 12 years ago
This is a bug report for perl from perl@wizbit.be\, generated with the help of perlbug 1.34 running under perl v5.8.3.
Hello\,
There is a difference in result between @hash{qw/a b c/}++ and @tied_hash{qx/a b c/} :
Example:
Case-1:
#!/usr/bin/perl -l $\,=qq( & );
package C; use Tie::Hash; @ISA=qw/Tie::StdHash/; sub STORE { print @_; }
package main; tie %x\, qq(C); @x{qw/a b c/}++
Output: C=HASH(0x815dc78) & c & 1
This means that the store routine is only called once\, even though it should be called for each element when a hash-slice is used.
Doing the same thing on a 'normal' hash will create the 3 keys\, where the first 2 have a value of undef\, and the last one a value of 1
Case-2: @x{qw/a b c/} = 1; # instead of @x{qw/a b c/}++
The result of this line is that the three keys are created\, the first one having the value 1 and the last two having a value of undef (which is the same behavoir as with a 'normal' hash)
Is this a bug or not? or it the @normal_hash{qx/a b c/}++ an 'accidental feature' which has not been copied to tie?
I believe it is a bug since this behaviour isn't documented in the perltie POD...
Can this be checked out?
Bram
Flags: category=core severity=low
Site configuration information for perl v5.8.3:
Configured by Debian Project at Sat Mar 27 17:07:14 EST 2004.
Summary of my perl5 (revision 5.0 version 8 subversion 3) configuration: Platform: osname=linux\, osvers=2.4.25-ti1211\, archname=i386-linux-thread-multi uname='linux kosh 2.4.25-ti1211 #1 thu feb 19 18:20:12 est 2004 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.3 -Dsitearch=/usr/local/lib/perl/5.8.3 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.3 -Dd_dosuid -des' hint=recommended\, useposix=true\, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O3'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include' ccversion=''\, gccversion='3.3.3 (Debian 20040314)'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='cc'\, ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.3.2.so\, so=so\, useshrplib=true\, libperl=libperl.so.5.8.3 gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-rdynamic' cccdlflags='-fPIC'\, lddlflags='-shared -L/usr/local/lib'
Locally applied patches:
@INC for perl v5.8.3: /etc/perl /usr/local/lib/perl/5.8.3 /usr/local/share/perl/5.8.3 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .
Environment for perl v5.8.3:
HOME=/root
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/bin/X11:/usr/local/sbin:/usr/local/bin:/usr/games
PERL_BADLANG (unset)
SHELL=/bin/bash
This means that the store routine is only called once\, even though it should be called for each element when a hash-slice is used.
Doing the same thing on a 'normal' hash will create the 3 keys\, where the first 2 have a value of undef\, and the last one a value of 1
There is only one store\, but there may be three fetches. The autovivification happens at fetch time.
post-increment appears to increment the last element of hash slices but not against arrays in general. Is this by design or laxity?
The RT System itself - Status changed from 'new' to 'open'
On Thu\, Mar 17\, 2005 at 11:08:00AM -0000\, Bram wrote:
Is this a bug or not? or it the @normal_hash{qx/a b c/}++ an 'accidental feature' which has not been copied to tie?
On Tue\, Mar 29\, 2005 at 05:30:27PM -0600\, David Nicol wrote:
post-increment appears to increment the last element of hash slices but not against arrays in general. Is this by design or laxity?
I assume that being able to increment a hash (or array) slice is a bug\, given that it's a syntax error on a plain array or hash:
$ perl -le '++@a; print foreach @a' Can't modify array dereference in preincrement (++) at -e line 1\, near "@a;" Execution of -e aborted due to compilation errors. $ perl -le '++@a[0..1]; print foreach @a'
1 $ perl -le '++%a; print foreach %a' Can't modify hash dereference in preincrement (++) at -e line 1\, near "%a;" Execution of -e aborted due to compilation errors. $ perl -le '++@a{0..1}; print foreach %a' 1 1 0
$
So presumably that bug for the regular case needs fixing (to become a syntax error) rather than tie being brought into line with it.
Nicholas Clark
In article \20050403195113\.GH96525@​plum\.\_lirble\.org\, Nicholas Clark \nick@​ccl4\.org writes:
On Thu\, Mar 17\, 2005 at 11:08:00AM -0000\, Bram wrote:
Is this a bug or not? or it the @normal_hash{qx/a b c/}++ an 'accidental feature' which has not been copied to tie?
On Tue\, Mar 29\, 2005 at 05:30:27PM -0600\, David Nicol wrote:
post-increment appears to increment the last element of hash slices but not against arrays in general. Is this by design or laxity?
I assume that being able to increment a hash (or array) slice is a bug\, given that it's a syntax error on a plain array or hash:
For golfers this is a well known fact :-)
As noted\, it works on array slices too:
perl -wle '@a=(1..4); @a[1..2]++; print for @a' 1 2 4 4
It's also sort of consistent. A slice is is documented to be a list of values\, and in fact the docs are quite explicit about @a[1..2] being like ($a[1]\, $a[2])\, though the usage of "list" is quite ambiguous in that part of perldoc perldata. But that's *really* the way it behaves.
e.g.:
perl -wle '@a=1..4; print for \@a[1..2]'
is not some array reference\, but:
SCALAR(0x817350c) SCALAR(0x8173518)
just like you'd get from \($a[1]\, $a[2])
And in scalar context such a list of values evaluates to the last value:
perl -wle '@a=1..4; print for scalar @a[0..2]' 3
So the result is actually as expected and I wouldn't call it a bug.
PS: At least until you see that this doesn't work:
perl -wle '@a=1..4; ($a[1]\, $a[2])++' Useless use of array element in void context at -e line 1. Too many arguments for postincrement (++) at -e line 1\, near ")++" Execution of -e aborted due to compilation errors.
Maybe THAT'S a bug :-)
On Sun Apr 03 16:22:34 2005\, perl5-porters@ton.iguana.be wrote:
In article \20050403195113\.GH96525@​plum\.\_lirble\.org\, Nicholas Clark \nick@​ccl4\.org writes:
On Thu\, Mar 17\, 2005 at 11:08:00AM -0000\, Bram wrote:
Is this a bug or not? or it the @normal_hash{qx/a b c/}++ an 'accidental feature' which has not been copied to tie?
On Tue\, Mar 29\, 2005 at 05:30:27PM -0600\, David Nicol wrote:
post-increment appears to increment the last element of hash slices but not against arrays in general. Is this by design or laxity?
I assume that being able to increment a hash (or array) slice is a bug\, given that it's a syntax error on a plain array or hash:
For golfers this is a well known fact :-)
As noted\, it works on array slices too:
perl -wle '@a=(1..4); @a[1..2]++; print for @a' 1 2 4 4
It's also sort of consistent. A slice is is documented to be a list of values\, and in fact the docs are quite explicit about @a[1..2] being like ($a[1]\, $a[2])\, though the usage of "list" is quite ambiguous in that part of perldoc perldata. But that's *really* the way it behaves.
e.g.:
perl -wle '@a=1..4; print for \@a[1..2]'
is not some array reference\, but:
SCALAR(0x817350c) SCALAR(0x8173518)
just like you'd get from \($a[1]\, $a[2])
And in scalar context such a list of values evaluates to the last value:
perl -wle '@a=1..4; print for scalar @a[0..2]' 3
So the result is actually as expected and I wouldn't call it a bug.
PS: At least until you see that this doesn't work:
perl -wle '@a=1..4; ($a[1]\, $a[2])++' Useless use of array element in void context at -e line 1. Too many arguments for postincrement (++) at -e line 1\, near ")++" Execution of -e aborted due to compilation errors.
Maybe THAT'S a bug :-)
The âtoo many argumentsâ thing is based on the number of operands at a syntactic level.
If an expression could (or usually would) return a list\, but is still one single term\, it gets evaluated in scalar context by operators that propagate scalar context.
A hash or array slice in scalar context evaluates to the last element of the slice.
$ perl -le' @_ = a..z; print scalar @_[0..5];' f
Hash and array slices are valid lvalues.
So I think this is not a bug\, and that the behaviour is as expected. Changing it would mean adding special cases.
--
Father Chrysostomos
@cpansprout - Status changed from 'open' to 'rejected'
On Fri\, Dec 2\, 2011 at 1:56 AM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
A hash or array slice in scalar context evaluates to the last element of the slice.
$ perl -le' @_ = a..z; print scalar @_[0..5];' f
Hash and array slices are valid lvalues.
So I think this is not a bug\, and that the behaviour is as expected. Changing it would mean adding special cases.
I agree\, but I don't understand your explanation about perl -we'@a=0..3; ($a[1]\, $a[2])++'?
The âtoo many argumentsâ thing is based on the number of operands at a
syntactic level.
There is only one operand: a list/comma op.
On Thu Dec 01 23:20:24 2011\, ikegami@adaelis.com wrote:
On Fri\, Dec 2\, 2011 at 1:56 AM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
A hash or array slice in scalar context evaluates to the last element of the slice.
$ perl -le' @_ = a..z; print scalar @_[0..5];' f
Hash and array slices are valid lvalues.
So I think this is not a bug\, and that the behaviour is as expected. Changing it would mean adding special cases.
I agree\, but I don't understand your explanation about perl -we'@a=0..3; ($a[1]\, $a[2])++'?
The âtoo many argumentsâ thing is based on the number of operands at a
syntactic level.
There is only one operand: a list/comma op.
++ is processed by ck_fun\, which works that way. Yes\, it is inconsistent with other ops\, and I would like to fix it some day\, but that is not the subject of this ticket\, and #96006 already covers that.
--
Father Chrysostomos
On Fri\, Dec 2\, 2011 at 11:15 AM\, Father Chrysostomos via RT \< perlbug-followup@perl.org> wrote:
++ is processed by ck_fun\, which works that way. Yes\, it is inconsistent with other ops\, and I would like to fix it some day\, but that is not the subject of this ticket\, and #96006 already covers that.
Excellent. Thanks.
Migrated from rt.perl.org#34470 (status was 'rejected')
Searchable as RT34470$