a=[] for i in ["hi","hello"] a<<Proc.new {i} end a.each do |m| puts m.call end
输出: hello hello 怎么不是 hi、hello,何解?
参见 http://graysoftinc.com/early-steps/the-evils-of-the-for-loop
运行时求值,拿到的是 i 的最终值,就是 hello 了。
另外,Ruby 中几乎从来不用 for 语句。
我的理解是在 each 中,每次循环时,Proc.new 创建的对象不同,而在 for 中 Proc.new 创建的始终是同 1 个对象,所以结果不同,可否这样理解?
可以这么理解
for i in [1,2,3,4] do end puts i #=> 4
这里的 i 不是 local variable,实际上相当于定义了一个 i 变量,它的作用域和 for 同级。
但是下面的 i 就是 local variable,它的作用域不在 block 外
[1,2,3,4].each do |i| end puts i #=> NameError: undefined local variable or method `i' for main:Object
按照 SICP 的说法,因为 for 不会产生 frame,所以这里的所有 i 都属于同一个 frame,proc 求值时会从这个 frame 里找 i 的绑定,i 最后绑定的是 hello,结果自然就是两个 hello 了
a = [] for i in %w[hi hello] a << Proc.new { i } end i = 'magic' a.each { |m| puts m.call }
楼主可以看看这个的执行结果
作用域在 ruby 中真是表现的淋漓尽致
绑定啊、frame 啊这些理解起来不直观,但貌似是那么回事