strange behaviour: array elements unexpectedly undeffed?

W

willem

running this script as

perl tst.pl < /dev/null

( or "perl tst.pl < nul" if you are running windows )

shows that the elements in the path array get modified if the loop
contains a '<>' operator.

is that a bug in perl? or am I missing something here.

I tried this with 5.8.3, 5.8.4, 5.8.5, various platforms ( freebsd,
linux, windows-cygwin, windows-activestate )

if you open a file, or pipe, and read it with <FH> the same thing
happens.

willem


-------------------------tst.pl
#!/usr/bin/perl -w
use strict;
#
# this script demonstrates how elements of the @path array
# get changed to 'undef' in the for loop when 'while(<>)'
# was executed somewhere in the loop
#
# I am not expecting @path to be changed by just looping over it.
#
my @path;
print "\n\n... array is fine just looping over it.\n\n";
@path=("usr", "bin");
writepath(\@path, "before first for");
for (@path) {
writepath(\@path, "in first for");
}

print "\n\n... array gets corrupted while reading from STDIN\n\n";
@path=("usr", "bin");
writepath(\@path, "before second for");
for (@path) {
writepath(\@path, "in second for");
while (<>) {
}
}
print "\n\n... and another element undeffed the next time\n\n";
writepath(\@path, "before third for");
for (@path) {
writepath(\@path, "in third for");
while (<>) {
}
}

sub writepath {
my $path= shift;
my $msg= shift;
print($msg, ": ", join(", ", map { sprintf("%d:%s", $_, defined
$path->[$_]?"ok":"NOTOK") } (0..$#$path) ), "\n");
}
 
I

itsme

is that a bug in perl? or am I missing something here.

found the problem, I should add 'local $_' before the while(<>).

still, I wonder if that should not happen implicitly?

willem
 
B

Brian McCauley

willem wrote:

is that a bug in perl? or am I missing something here.

You are missing the statement "The $_ variable is not implicitly
localized" in the documentation of the while(<>) construct.

http://search.cpan.org/~nwclark/perl-5.8.5/pod/perlop.pod#I/O_Operators

The documentation goes on to say: "You'll have to put a local $_; before
the loop if you want that to happen."

Do _not_ do this. Always localize *_ not $_. Getting into the habit of
doing local($_) will cause _very_ hard to find bugs when one day $_
happens to be an alias to an element of a tied agregate.
 
D

David K. Wall

Brian McCauley said:
willem wrote:

[ snip observation that $_ not implicitly localized by the
while(<>) construct ]
[snip]
The documentation goes on to say: "You'll have to put a local $_;
before the loop if you want that to happen."

Do _not_ do this. Always localize *_ not $_. Getting into the
habit of doing local($_) will cause _very_ hard to find bugs when
one day $_ happens to be an alias to an element of a tied
agregate.

Voice of experience? :)
 
U

Uri Guttman

BM> You are missing the statement "The $_ variable is not implicitly
BM> localized" in the documentation of the while(<>) construct.

BM> The documentation goes on to say: "You'll have to put a local $_;
BM> before the loop if you want that to happen."

BM> Do _not_ do this. Always localize *_ not $_. Getting into the habit
BM> of doing local($_) will cause _very_ hard to find bugs when one day $_
BM> happens to be an alias to an element of a tied agregate.

i like my solution better. i (almost) never use implict $_ in loops (or
anywhere). instead i use my variables which don't have scoping issues
and provide more information to the reader of the code. i only use $_
where forced to (map/grep) and in a few rare cases where it does help
the code quality.

i have never run into the nesting looped $_ bug because of this habit
and i find it amusing to see how often it traps newbies.

uri
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,408
Latest member
AlenaRay88

Latest Threads

Top