Ruby 1.9提供了定义块的本地变量而不关闭外部作用域中同名变量的能力:
x = 10
proc { |;x|
x = 20
}.call
x #=> 10
我希望将此行为作为我定义的某些块的默认行为 - 而不必使用|; x,y,z |语法(注意分号)。
我认为Ruby不允许这样做,但是有可能破解这个功能吗?
我目前有一个解决方案,但它非常难看,因为它需要检查在块结束时哪些局部变化,然后将它们恢复到块之前的值。我不介意你的解决方案是否需要在块的开头指定哪些变量是块本地的,scope(:x) { x = 20 }
答案 0 :(得分:7)
我选择的解决方案是基于bobbywilson0的想法。以下是它的工作原理:
x = 99
y = 98
scope { |x, y|
x = 20
y = 30
}
x #=> 99
y #=> 98
这很有用,因为scope
中使用的变量是在作用域的开头创建的,不会关闭在它之外定义的任何变量,它们也是在作用域末尾的GC。 / p>
以下是实施:
def scope(&block)
num_required = block.arity >= 0 ? block.arity : ~block.arity
yield *([nil] * num_required)
end
此解决方案还会考虑默认值,使其在功能上等同于lisp中的let*
。
scope { |x = 20, z = (x * 3)|
x #=> 20
z #=> 60
}
我在这里写了博客:http://banisterfiend.wordpress.com/2010/01/07/controlling-object-scope-in-ruby-1-9/
答案 1 :(得分:4)
x = 10; proc{ |x| x = 20 }.call(0)