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]

Reply via email to