如何在ruby proc / lambda中使用真正的局部变量

初学Ruby问题。 更改此代码的最简单方法是什么,但是将块完全保留 ,可以消除副作用?

$ irb irb(main):001:0> x = lambda {|v| x=2 irb(main):002:1> v} => # irb(main):003:0> x.call(3) => 3 irb(main):004:0> x => 2 

这是我可以设法说明我的问题的最简单的例子,因此“删除赋值”或“不将Proc分配给x”不是我正在寻找的。

我想在Proc(或lambda)中设置可以分配的局部变量,而不会影响原始的封闭范围。 我可以动态创建一个类或模块来包装块,但这对于这样一个基本的东西来说似乎有些过分。

等价Python到我正在尝试做的事情:

 def x(v): x = 2 # this is a local variable, what a concept return v 

有时它是理想的行为:

 total = 0 (1..10).each{|x| total += x} puts total 

但有时这是偶然的,你不想搞乱一个碰巧有同名的外部变量。 在这种情况下,请使用分号和块局部变量列表来跟踪参数列表:

 x = lambda{|v; x| x = 2; v} p x.call(3) #3 px # 

原因是lambda绑定到它的定义范围(而不是它的调用范围),并且是一个完整的闭包,除其他外,它包括局部变量x 。 你真正想要的是一个未绑定的proc来传递和调用没有任何特殊的绑定。 根据设计,这不是Ruby非常容易做到的事情(可以使用eval,但这不是一个块,而只是一个字符串语句)。 Procs,lambdas和blocks都绑定到它们的定义范围。 词法范围仅建立在类,模块和方法上; 不在块/ procs / lambdas /其他任何东西上。

值得注意的是,Python甚至不允许首先在lambdas中进行赋值。