ruby1.9是如何实现闭包内的循环变量(局部变量)x和外部同名变量x无关的?

ruby1.9是如何实现闭包内的局部变量x和外部同名变量x无关的?
x = 15

(1..5).each do |x|

puts x

end

puts x # -> 15

这个……不知道楼主要问的是语言本身的设计还是底下具体的实现。后者的话我觉得需要掌握一些编译相关的基础知识再去看会比较轻松些。

前者的话,Ruby 1.9对block的作用域规则做了修改,使得block的参数中如果有跟外部环境的变量同名的,前者会在block内隐藏前者的作用域。楼主的例子就反映了这点。
但观察这个情况:
[code="irb"]irb(main):001:0> x = 15
=> 15
irb(main):002:0> (1..5).each do |i|
irb(main):003:1* puts x = i
irb(main):004:1> end
1
2
3
4
5
=> 1..5
irb(main):005:0> x
=> 5[/code]
像这样,在block里用了x,但x不是block的参数,而且在外部已经有x的定义,那么对x的改变照样会反映到外部。
所以,为了保证一个变量的作用域局限在block内部,在Ruby 1.9中除了声明参数外,还可以声明局部变量:
[code="irb"]irb(main):001:0> x = 15
=> 15
irb(main):002:0> (1..5).each do |i;x|
irb(main):003:1* puts x = i
irb(main):004:1> end
1
2
3
4
5
=> 1..5
irb(main):005:0> x
=> 15[/code]
在原本表示参数列表的两个竖线中,分号前面的是参数声明,分号后面的是局部变量声明。