如何使块本地变量成为ruby 1.9中的默认值?

hor*_*guy 3 ruby closures scope

Ruby 1.9提供了定义块的本地变量并且不关闭外部作用域中同名变量的能力:

x = 10
proc { |;x|
    x = 20
}.call
x #=> 10
Run Code Online (Sandbox Code Playgroud)

我希望将此行为作为我定义的某些块的默认行为 - 而不必使用|; x,y,z | 语法(注意分号).

我不认为Ruby允许本机,但是有可能破解这个功能吗?

我目前有一个解决方案,但它非常难看,因为它需要检查在块结束时查看哪些局部变化,然后将它们恢复为块之前的值.我不介意你的解决方案是否需要在块的开头指定哪些变量是块本地的,即scope(:x) { x = 20 }

hor*_*guy 7

我选择的解决方案是基于bobbywilson0的想法.下面是它的工作原理:

x = 99
y = 98

scope { |x, y|
    x = 20
    y = 30
}

x #=> 99
y #=> 98 
Run Code Online (Sandbox Code Playgroud)

这很有用,因为在scope作用域开始时创建的变量不会关闭在其外部定义的任何变量,它们在作用域的末尾也是GC.

这是实施:

def scope(&block)
    num_required = block.arity >= 0 ? block.arity : ~block.arity
    yield *([nil] * num_required)
end
Run Code Online (Sandbox Code Playgroud)

此解决方案还考虑了默认值,使其在功能上等同于let*in lisp.

scope { |x = 20, z = (x * 3)| 
    x #=> 20
    z #=> 60
}
Run Code Online (Sandbox Code Playgroud)

我在这里写博客:http://banisterfiend.wordpress.com/2010/01/07/controlling-object-scope-in​​-ruby-1-9/