http://www.perlmonks.org?node_id=470179

Marcello has asked for the wisdom of the Perl Monks concerning the following question:

This problem is very difficult to describe, I will try to give as many details as possible in the hope someone out there understands what is going on.

A large Perl application contains a hash which contains an array. The application forks of two child processes using this array:
foreach (@{ $HASH{"IP"} }) { # Please note $_ is used here # IP contains two IP addresses ... forking goes here ... }
After the fork, the child process creates several objects, one of which gets gets a reference to this hash. This process then calls an object function which alters the $_ variable. The reference to the hash is never changed nor used.

After this function call, the IP array in the hash has mysteriously changed in the child process! The Xth element (either 0 or 1) of the corresponding child process has the exact same value as $_, which was set in another object.

If I change the foreach to:
foreach my $notUsed (@{ $HASH{"IP"} }) { # Please note $_ is NOT used here # IP contains two IP addresses ... forking goes here ... }
the IP array in the hash is not altered anymore. So it appears the $_ variable has something to do with it, but I do not see where this goes wrong. Especially because the IP array is not altered anywhere in the application and the $_ is changed in another package. I suspect it's a problem with the forking, the reference to the hash and the $_ variable.

Does anyone have a clue?

Regards, Marcel

Replies are listed 'Best First'.
Re: Reference and $_ weirdness
by Joost (Canon) on Jun 27, 2005 at 09:34 UTC
    foreach aliases the $_ or $notUsed variables to the indexed element. That means that any changes to those variables will also change the array. Since $_ is a global (local()ized by foreach), that means that any changes to $_ without localizing it again will change the aliased element.

    Solution: make sure $_ is localized before modifying it. Or use a lexical variable instead, like you do.

      Thank you for the clear answer.

      Indeed the $_ variable was not localized in the specific functions.

      Will check the rest of the application for this bug too.