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]