|
List Info
Thread: Looping "foreach my $thing(@things)" places a reference not a scalar into $thing
|
|
| Looping "foreach my
$thing(@things)" places a reference
not a scalar into $thing |

|
2007-08-30 01:07:39 |
# New Ticket Created by Worik
# Please include the string: [perl #45041]
# in the subject line of all future correspondence about
this issue.
# <URL: h
ttp://rt.perl.org/rt3/Ticket/Display.html?id=45041 >
This is a bug report for perl from worik.stanton gmail.com,
generated with the help of perlbug 1.35 running under perl
v5.8.8.
------------------------------------------------------------
-----
[Please enter your report here]
This little programme demonstrates the problem
my test = (1..12);
print join(", ", test)."n";
foreach my $t( test){
if($t % 2 ){
$t *= -1;
}
}
print join(", ", test)."n";
The output is:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12
The output should be:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
[Please do not change anything below this line]
------------------------------------------------------------
-----
---
Flags:
category=core
severity=high
---
Site configuration information for perl v5.8.8:
Configured by Debian Project at Tue Mar 6 01:52:23 UTC
2007.
Summary of my perl5 (revision 5 version 8 subversion 8)
configuration:
Platform:
osname=linux, osvers=2.6.15.7,
archname=i486-linux-gnu-thread-multi
uname='linux rothera 2.6.15.7 #1 smp sat sep 30 10:21:42
utc 2006
i686 gnulinux '
config_args='-Dusethreads -Duselargefiles
-Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -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.8
-Dsitearch=/usr/local/lib/perl/5.8.8
-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.8 -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 -pipe -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
-DDEBIAN
-fno-strict-aliasing -pipe -I/usr/local/include'
ccversion='', gccversion='4.1.2 (Ubuntu
4.1.2-0ubuntu4)',
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.5.so, so=so, useshrplib=true,
libperl=libperl.so.5.8.8
gnulibc_version='2.5'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared
-L/usr/local/lib'
Locally applied patches:
---
INC
for perl v5.8.8:
/etc/perl
/usr/local/lib/perl/5.8.8
/usr/local/share/perl/5.8.8
/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.8:
HOME=/home/worik
LANG=en_NZ.UTF-8
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
:/bin:/usr/games
PERL_BADLANG (unset)
SHELL=/bin/bash
--
They laughed at Einstein. They laughed at the Wright
Brothers. They
laughed at Bozo the Clown.
|
|
| Re: Looping "foreach my
$thing(@things)" places a reference
not a scalar into $thing |

|
2007-08-30 10:02:24 |
Worik (via RT) wrote:
> This little programme demonstrates the problem
>
> my test = (1..12);
> print join(", ", test)."n";
> foreach my $t( test){
> if($t % 2 ){
> $t *= -1;
> }
> }
> print join(", ", test)."n";
>
> The output is:
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
> -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12
>
> The output should be:
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Thank you for your report.
This is a feature for the foreach loop. The foreach
iterator is aliased to
each element of the array so modifying $t will modify each
element in the
array in turn. This is documented (somewhat obtusely) in
perlsyn...
If any element of LIST is an lvalue, you can modify
it by modifying VAR
inside the loop. Conversely, if any element of LIST
is NOT an lvalue,
any attempt to modify that element will fail. In
other words, the
"foreach" loop index variable is an
implicit alias for each item in the
list that you're looping over.
Since I was under the illusion that aliasing only happened
when $_ is used,
I've added an entry on the wiki about this trap.
http://www.perlfoundation.org/perl5/index.cgi?fore
ach_aliasing
--
Stabbing you in the face so you don't have to.
|
|
| Re: Looping "foreach my
$thing(@things)" places a reference
not a scalar into $thing |

|
2007-08-30 10:20:44 |
On 8/30/07, via RT Worik <perlbug-followup perl.org> wrote:
> # New Ticket Created by Worik
> # Please include the string: [perl #45041]
> # in the subject line of all future correspondence
about this issue.
> # <URL: h
ttp://rt.perl.org/rt3/Ticket/Display.html?id=45041 >
>
>
> This is a bug report for perl from worik.stanton gmail.com,
> generated with the help of perlbug 1.35 running under
perl v5.8.8.
>
>
>
------------------------------------------------------------
-----
> [Please enter your report here]
> This little programme demonstrates the problem
>
> my test = (1..12);
> print join(", ", test)."n";
> foreach my $t( test){
> if($t % 2 ){
> $t *= -1;
> }
> }
> print join(", ", test)."n";
As Michael Schwern said, this turns out to be the way the
for/foreach
loop is documented to work. Using aliasing, makes it more
efficient
(but dangerous for the unaware as you have discovered for
your self).
To loop through an array, without worrying about changing
the contents
of the array elements, you may use an idiom like that
foreach ( test){
my $t = $_; # makes a copy
if($t % 2 ){
$t *= -1;
}
}
> The output is:
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
> -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12
>
> The output should be:
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
>
>
>
> [Please do not change anything below this line]
>
------------------------------------------------------------
-----
> ---
> Flags:
> category=core
> severity=high
> ---
> Site configuration information for perl v5.8.8:
>
> Configured by Debian Project at Tue Mar 6 01:52:23 UTC
2007.
>
> Summary of my perl5 (revision 5 version 8 subversion 8)
configuration:
> Platform:
> osname=linux, osvers=2.6.15.7,
archname=i486-linux-gnu-thread-multi
> uname='linux rothera 2.6.15.7 #1 smp sat sep 30
10:21:42 utc 2006
> i686 gnulinux '
> config_args='-Dusethreads -Duselargefiles
-Dccflags=-DDEBIAN
> -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu
-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.8
> -Dsitearch=/usr/local/lib/perl/5.8.8
-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.8 -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 -pipe
-I/usr/local/include
> -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
> optimize='-O2',
> cppflags='-D_REENTRANT -D_GNU_SOURCE
-DTHREADS_HAVE_PIDS -DDEBIAN
> -fno-strict-aliasing -pipe -I/usr/local/include'
> ccversion='', gccversion='4.1.2 (Ubuntu
4.1.2-0ubuntu4)',
> 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.5.so, so=so, useshrplib=true,
> libperl=libperl.so.5.8.8
> gnulibc_version='2.5'
> Dynamic Linking:
> dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-Wl,-E'
> cccdlflags='-fPIC', lddlflags='-shared
-L/usr/local/lib'
>
> Locally applied patches:
>
>
> ---
> INC for perl v5.8.8:
> /etc/perl
> /usr/local/lib/perl/5.8.8
> /usr/local/share/perl/5.8.8
> /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.8:
> HOME=/home/worik
> LANG=en_NZ.UTF-8
> LANGUAGE (unset)
> LD_LIBRARY_PATH (unset)
> LOGDIR (unset)
>
>
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
:/bin:/usr/games
> PERL_BADLANG (unset)
> SHELL=/bin/bash
>
> --
> They laughed at Einstein. They laughed at the Wright
Brothers. They
> laughed at Bozo the Clown.
>
>
|
|
[1-3]
|
|