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
user name
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.stantongmail.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
user name
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
user name
2007-08-30 10:20:44
On 8/30/07, via RT Worik <perlbug-followupperl.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.stantongmail.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]

about | contact  Other archives ( Real Estate discussion Medical topics )