in reply to 'for' array being altered - scope

While I don't see where $_ is changed, keep in mind that it is global. It could be format_column_range or any other code invoked from this that changes it -- even though $_ is not explicitly passed to it.

I once accidently clobbered $_ because I had a method that, upon first execution, would read a config file. while(<FILE>){} does not look like it would clobber a global, does it? Took me longer than I liked to spot it ...

The Sidhekin
print "Just another Perl ${\(trickster and hacker)},"

Replies are listed 'Best First'.
Re: Re: 'for' array being altered - scope
by diotalevi (Canon) on Sep 26, 2002 at 12:18 UTC
    Two things here: Sidhekin's problem can be solved by localizing $_ to the current sub instead of just using it. As for the original problem, when you iterate over an array with for() the $_ variable is aliased to the right spot in @array. It *is* your array entry so if you assign to $_ then you are assigning to that spot in your array. It allows for clever things like avoiding an assign operation where map{} would require you to assign the value back into place. This is a micro optimization but it' still a good method to know of.
    @mg = qw(Sam sat on the ground and put his head in his hands. 'I wish + I had never come here, and I don't want to see no more magic,' he sa +id, and fell silent.); ## standard way # create a new array and assign back into place @mg = map ucfirst, @mg; # OR... ## work in place # alter existing array $_ = ucfirst() for @mg;

    Update And this reply misses the entire point of the original question. Oopsie!

      That's all very correct1 and appreciated, but it tells neither me nor fireartist anything we did not already know.

      See, in my case localizing $_ had to be done in the sub that assigned to it (local does dynamic scoping, not lexical), and my problem was finding which sub did such a nasty thing.

      find -name '*.pm' | xargs grep '$_ =' did nothing to help me ...

      fireartist's problem is similar. He knows that assigning to $_ has this effect. He just does not see where this assignment takes place.

      1 <nitpick>... except that you are not so much avoiding assign operations as avoiding building a temporary array. The map version performs one assignment (to an array) total, while the for version performs one assignment (to a scalar) each time through the loop. Still, it is an optimization.</nitpick>

      The Sidhekin
      print "Just another Perl ${\(trickster and hacker)},"

        Duh! smacks forehead oops! Ok in that case it would be interesting to know where column_num lives to examine that source.