如何在另一个lambda体内"粘合"一个lambda?

Kar*_*lak 1 ruby lambda

说我在Ruby中有这两个lambdas:

lambda1 = -> { puts 'lambda1' }
lambda2 = -> {
  puts 'lambda2 calls lambda1'
  lambda1.()
}
Run Code Online (Sandbox Code Playgroud)

它按预期工作:

lambda1.()
# lambda1
lambda2.()
# lambda2 calls lambda1
# lambda1
Run Code Online (Sandbox Code Playgroud)

但是现在如果我删除lambda1,lambda2将停止工作:

lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)

NoMethodError:nil的未定义方法`call':NilClass

我能做些什么,以"胶水"我lambda1lambda2,使第一,第二的固有部分,避免这种情况?

Max*_*Max 5

问题是你在一个闭包中lambda2捕获变量lambda1,因此它会在lambda1以后更改时注意到.解决方案只是让它捕获一个不同的变量:

lambda1 = -> { puts 'lambda1' }
x = lambda1 # copy the reference
lambda2 = -> { x.() }
lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)

"但这也有同样的问题!" 你可能会说,"我可以通过重新分配来打破它x!" 好吧,然后使它x受范围保护:

def wrap x
  -> { x.() }
end

lambda1 = -> { puts 'lambda1' }
lambda2 = wrap lambda1
lambda1 = nil
lambda2.()
Run Code Online (Sandbox Code Playgroud)