Using the same variable for an array and an iterator

I’ve just started learning Ruby and am going through a few tutorials.
Right now I’m playing around with arrays and am getting a strange
error. I am creating an array named ‘x’ and creating an iterator
named x as well. Now I know that this isn’t good practice but I’m
getting a strange error. The first time I iterate through the entire
array, simply displaying the contents of the array, I don’t get an
error at all. If I immediately run the iteration again I get a
NoMethodError and am trying to figure out why. Here’s a screenshot
http://bit.ly/bXZkjp
Like I said, I know that this is bad practice, but I’m curious as to
what is causing this error only after the first go through.

Ryan wrote:

I’ve just started learning Ruby and am going through a few tutorials.
Right now I’m playing around with arrays and am getting a strange
error. I am creating an array named ‘x’ and creating an iterator
named x as well. Now I know that this isn’t good practice but I’m
getting a strange error. The first time I iterate through the entire
array, simply displaying the contents of the array, I don’t get an
error at all. If I immediately run the iteration again I get a
NoMethodError and am trying to figure out why. Here’s a screenshot
http://bit.ly/bXZkjp
Like I said, I know that this is bad practice, but I’m curious as to
what is causing this error only after the first go through.

The error gives a hint as to what’s happening. In Ruby 1.8, variables in
a block clobber the variables of the outside scope. So your in your
example, after each is finished iterating, “x” is now 4, even though x
was defined within that block.

In Ruby 1.9 variables only exist within the scope they’re declared in,
so that doesn’t have this problem.

On Sat, Sep 25, 2010 at 11:30 AM, Ryan [email protected] wrote:

what is causing this error only after the first go through.
Ruby 1.8 doesn’t shadow local variables used as block arguments.
That means what happens is that x is assigned the current element of
the array, until the iteration is finished (x = 4).
Then you try to call 4.each, which doesn’t exist.

See for comparison the 1.9 output with warnings enabled:

iota ~ % ruby -vwe ‘x = [1,2,3,4]; x.each{|x| p x }; x.each{|x| p x }’
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]
-e:1: warning: shadowing outer local variable - x
-e:1: warning: shadowing outer local variable - x
1
2
3
4
1
2
3
4

As you can see, 1.9 shadows the outer variable, so the original is not
changed.

On Sep 24, 10:55 pm, Michael F. [email protected] wrote:

Like I said, I know that this is bad practice, but I’m curious as to
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]

As you can see, 1.9 shadows the outer variable, so the original is not changed.


Michael F.
CTO, The Rubyists, LLC

Ahh, that makes a lot of sense. Thanks guys.

-Ryan