At 07:45 PM 2/25/02 +0100, Birgit Kellner wrote: >Small question: I thought when doing a for loop over an array, I can >simply do this: >for (@array) { # do stuff with $_ } > >Now I have this situation: > >for (@array) { # contains a bunch of numbers > my %hash = &get_record($_); >} >foreach (@array) { print "$_\n";\ # problem - $_ is not the array element >anymore > >sub get_record { >my $key = shift; >my %hash; >open (FILE, "<$file") || die ("can't open $file: $!"); >LINE: while (<FILE>) { my $line = $_; chomp ($line); >my @data = split/\|/, $line; >if ($data[$db_key_pos] eq "$key") { # $db_key_pos is a global > for (my $i = 0; $i <= $#db_cols; $i++) { # Map > the array columns to a hash. @db_cols is a global > $rec{$db_cols[$i]} = $data[$i]; > } > last LINE; > } # end if >} #end while >close DB; >return (%hash); >} > >The line commented with "problem" now has the last value of $line from the >subroutine get_record as $_, and no longer the original array element. Can >it be that the subroutine somehow assigns something else to $_ and that >this assignment is then taken over in the code from where it's called?
The problem is that for loops localize their $_, but while loops don't. <plug> This is summed up in a bullet on p.57 of my book as, "When using a while loop that sets $_, localize $_ first if it might be called from elsewhere. </plug> Here run this: my @array = qw(one two three); print "Before: @array"; for (@array) { foo($_) } print "After: @array"; sub foo { my @foo = qw(dog cat bird); while ($_ = pop @foo) { last; } } Change that to say while (local $_ = pop @foo) { and you're fine. In your code, the assignment to $_ is by virtue of the while (<...>), so just put a local $_; in the sub before that line. -- Peter Scott Pacific Systems Design Technologies http://www.perldebugged.com -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]