Robert Klemme
10/20/2007 9:26:00 AM
On 19.10.2007 21:19, Andreas S wrote:
> Hopefully (I'm sure) somebody can shed a light on this. This caught me by surprise
>
> 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?
The reason for the behavior you are seeing is different scoping. "for"
does not open a new scope while block parameters sit in a different
scope. Apart from that "for" is a keyword (i.e. part of the language)
while "each" is just a method like other methods.
irb(main):014:0> def f1(x) x.each {|y| p y}; p y end
=> nil
irb(main):015:0> def f2(x) for y in x; p y; end; p y end
=> nil
irb(main):016:0> f1 %w{foo bar baz}
"foo"
"bar"
"baz"
NameError: undefined local variable or method `y' for main:Object
from (irb):14:in `f1'
from (irb):16
from :0
irb(main):017:0> f2 %w{foo bar baz}
"foo"
"bar"
"baz"
"baz"
=> nil
irb(main):018:0>
I'd say it's a good thing because you get the choice - if you need the
iteration variable after the block then use "for" - otherwise use "each".
Kind regards
robert