Forum: Ruby the difference between for-loop and each

Posted by Andreas S (Guest)
on 2007-10-19 21:22
(Received via mailing list)
Hopefully (I'm sure) somebody can shed a light on this. This caught me 
by surprise

ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]
test.rb:
TEST = []
def procs &block
  TEST << block
end

#for n in [1,2,3] do
[1,2,3].each do |n|
  procs do
    puts "#{n}"
  end
end

TEST.each do |t|
  puts t
  t.call
end

With for loop
>> ruby test.rb
#
3
#
3
#
3

With each
>> ruby test.rb
#
1
#
2
#
3

I thought for-loop behaves the same as each. Apparently not. Why is this 
and is this a good thing?

Thank you in advance
-andre
Posted by Sean O'halpin (sean)
on 2007-10-20 01:19
(Received via mailing list)
On 10/19/07, Andreas S <andreas_s@hotmail.com> wrote:
> end
>   t.call
>
> and is this a good thing?
>
> Thank you in advance
> -andre
>

They are not quite the same. for does not introduce a new scope, whereas
each does. So, each time through the for loop, the closures you are 
stashing
in TEST are all referencing the same scope. When you run the stashed 
procs,
you are in that same scope, n has the value 3 at the end the for 
statement
so that is what is printed.

In the each version, you get a new scope and hence a new n each time 
through
the loop, so the value of n saved in each closure is different.

Try the following:

  for n in [1, 2, 3] do puts n end
  puts n
  [1, 2, 3].each do |m| puts m end
  puts m

As for rationale - for is slightly faster (no new scope has to be 
created
each time round the loop) and is similar in appearance to for statements 
in
other languages. However, the scope issue breaks it in my opinion and I
never use it.

Regards,
Sean
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.