Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overwriting with scalar $_ using foreach over array and inner wh ile loop #895

Closed
p5pRT opened this issue Nov 26, 1999 · 3 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Nov 26, 1999

Migrated from rt.perl.org#1828 (status was 'resolved')

Searchable as RT1828$

@p5pRT
Copy link
Author

p5pRT commented Nov 26, 1999

From Bernd.Koester@m.dasa.de

Using default scalar $_ (implicit) in an foreach loop over an array
and having an inner while loop reading a file we noticed that perl is
overwriting the scalar of the outer loop inserting read lines
from the file into the array.

my @​array=(1,2,3);
foreach (@​array) {
  open FILE, "<test";
  while <FILE> {
  ...
  }
  close FILE;
  }

FILE contains just one character (a).
After this procedure @​array contains (a,a,a)!
Best regards,

Bernd and Dirk

Perl Info


Site configuration information for perl 5.00503:

Configured by root at Mon May 10 10:54:22 MET DST 1999.

Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration:
  Platform:
    osname=solaris, osvers=2.5, archname=sun4-solaris
    uname='sunos sunny2 5.5 generic sun4m sparc sun4m '
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef useperlio=undef d_sfio=undef
  Compiler:
    cc='cc', optimize='-O', gccversion=
    cppflags='-I/usr/local/include'
    ccflags ='-I/usr/local/include'
    stdchar='unsigned char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldl -lm -lc -lcrypt
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-KPIC', lddlflags='-G -L/usr/local/lib'



@INC for perl 5.00503:
	/usr/local/lib/perl5/5.00503/sun4-solaris
	/usr/local/lib/perl5/5.00503
	/usr/local/lib/perl5/site_perl/5.005/sun4-solaris
	/usr/local/lib/perl5/site_perl/5.005
	.


Environment for perl 5.00503:
    HOME=/usr/users/sunny6/ko26619
    LANG (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
 
PATH=/usr/users/sunny6/ko26619:/usr/users/sunny6/ko26619/tools:/disks/disk1/
oracle/733/bin:/usr/users/sunny6/csdb/v0.2/lib:/disks/disk1/adobe/Acrobat3/b
in:/usr/users/sunny6/ko26619:/otn/sunny11/d7/a701/adept/bin:/otn/sunny11/d7/
a701/adept/bin/sun4r5:/otn/sunny11/d7/a701/adept/bin/sun4r5/dasa:/otn/sunny1
1/d7/a701/adept/lib/sun4r5:/usr/bin/X11:/otn/sunny11/d7/a701/csdb/lib:/otn/s
unny11/d7/csdb/idb_com:/opt/bin:/bin:/usr/bin:/usr/ccs/bin:/usr/local/bin:/u
sr/local:/usr/openwin/bin:/usr/new:/usr/hosts:/opt/SUNWspro/bin:/usr/users/s
unny6/ko26619:/otn/sunny11/d7/o40l/csdb/lib:/otn/sunny11/d7/o40l/omle40/bin:
/usr/users/sunny6/ko26619:/usr/users/sunny6/ko26619/tools:/disks/disk1/oracl
e/733/bin:/usr/users/sunny6/csdb/v0.2/lib:/disks/disk1/adobe/Acrobat3/bin:/u
sr/users/sunny6/ko26619:/otn/sunny11/d7/a701/adept/bin:/otn/sunny11/d7/a701/
adept/bin/sun4r5:/otn/sunny11/d7/a701/adept/bin/sun4r5/dasa:/otn/sunny11/d7/
a701/adept/lib/sun4r5:/usr/bin/X11:/otn/sunny11/d7/a701/csdb/lib:/otn/sunny1
1/d7/csdb/idb_com:/opt/bin:/bin:/usr/bin:/usr/ccs/bin:/usr/local/bin:/usr/lo
cal:/usr/openwin/bin:/usr/new:/usr/hosts:/opt/SUNWspro/bin:/usr/users/sunny6
/ko26619:/otn/sunny11/d7/o40l/csdb/lib:/otn/sunny11/d7/o40l/omle40/bin:/usr/
bin::/otn/sunny11/d7/o40l/omni40/bin:/otn/sunny11/d7/o40l/flexlm-5.12a/bin:/
usr/local/bin/netscape:.:/otn/sunny11/d7/o40l/omni40/bin:/otn/sunny11/d7/o40
l/flexlm-5.12a/bin:/usr/local/bin/netscape:.
    PERL=/disks/disk1/csdb/www/v0.2/csdb-perl
    PERL_BADLANG (unset)
    SHELL=/usr/bin/ksh

@p5pRT
Copy link
Author

p5pRT commented Nov 26, 1999

From [Unknown Contact. See original ticket]

Koester, Bernd writes​:
| Using default scalar $_ (implicit) in an foreach loop over an array
| and having an inner while loop reading a file we noticed that perl is
| overwriting the scalar of the outer loop inserting read lines
| from the file into the array.
|
| my @​array=(1,2,3);
| foreach (@​array) {
| open FILE, "<test";
| while <FILE> {
| ...
| }
| close FILE;
| }
|
|
| FILE contains just one character (a).
| After this procedure @​array contains (a,a,a)!

This is not a bug​:

man perlsyn ------------------------------------------------------------

The foreach modifier is an iterator​: For each value in EXPR, it aliases
$_ to the value and executes the statement.


man perlop -------------------------------------------------------------

If and ONLY if the input symbol is the only thing inside the conditional
of a while or for(;;) loop, the value is automatically assigned to the
variable $_.


Hence the while loop assigns to $_ which is an alias into @​array. No
surprise.

Mx.

@p5pRT
Copy link
Author

p5pRT commented Nov 26, 1999

From [Unknown Contact. See original ticket]

Martyn Pearce <m.pearce@​inpharmatica.co.uk> wrote

Hence the while loop assigns to $_ which is an alias into @​array. No
surprise.

But you haven't pointed out the key issue, that while never localises
any variable, unlike foreach. And this point isn't stressed in
the current (5.005_03) documentation.

The development version (5.005_62) makes this more explicit​:

---------------------pod/perlop.pod--------------------
Ordinarily you must assign the returned value to a variable, but
there is one situation where an automatic assignment happens. If
and only if the input symbol is the only thing inside the conditional
of a C<while> statement (even if disguised as a C<for(;;)> loop),
the value is automatically assigned to the global variable $_,
destroying whatever was there previously. (This may seem like an
odd thing to you, but you'll use the construct in almost every Perl
script you write.) The $_ variables is not implicitly localized.
You'll have to put a C<local $_;> before the loop if you want that
to happen.


I think the attached patch to perlsyn would also be useful.

Mike Guy

Inline Patch
--- ./pod/perlsyn.pod.orig	Fri Sep 17 21:23:08 1999
+++ ./pod/perlsyn.pod	Fri Nov 26 16:02:15 1999
@@ -163,6 +163,8 @@
 refers to the innermost enclosing loop.  This may include dynamically
 looking back your call-stack at run time to find the LABEL.  Such
 desperate behavior triggers a warning if you use the B<-w> flag.
+Unlike a C<foreach> statement, a C<while> statement never implicitly
+localises any variables.
 
 If there is a C<continue> BLOCK, it is always executed just before the
 conditional is about to be evaluated again, just like the third part of a

End of patch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant