Using the same variable for an array and an iterator

R

Ryan

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.
 
M

Michael Fellinger

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. =C2=A0I am creating an array named 'x' and creating an iterator
named x as well. =C2=A0Now I know that this isn't good practice but I'm
getting a strange error. =C2=A0The first time I iterate through the entir= e
array, simply displaying the contents of the array, I don't get an
error at all. =C2=A0If I immediately run the iteration again I get a
NoMethodError and am trying to figure out why. =C2=A0Here'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.

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 =3D 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 =3D [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 chan=
ged.

--=20
Michael Fellinger
CTO, The Rubyists, LLC
 
P

Paul Harrington

Ryan said:
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.
 
R

Ryan

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.

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.

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

-Ryan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top