我发现在以下模式中不使用闭包很难编程:
function outerFunction(input) {
var closureVar = "I'm here with ";
function innerFunction() {
return closureVar + input;
}
return innerFunction();
}
outerFunction('outer input'); // I'm here with outer input
这对我来说很有意义。 outerFunction 定义了 innerFunction 在调用时引用的环境。
我想看看 Ruby 如何完成同样的事情。我了解 Ruby 使用 block 、过程和 lambas,但我似乎无法实现与 JavaScript 相同的词法范围。
Ruby 天真的尝试:
def outer_function
list = [ 1, 2, 3 ]
list.each { |item| print item }
end
# Fails because list has an undefined method on the second iteration of the loop
又一次尝试
def outer_function
list = Proc.new { return [ 1, 2, 3 ] }
list.call.each { |item| another_function item }
end
def another_function item
puts item
end
# Same problem
那么,我怎样才能在 Ruby 中实现这种模式呢?
最佳答案
虽然 Javascript 有一种类型的 lambda 构造(匿名函数),但 Ruby 有多种。最常见的是 block (在您的示例中传递给 each
中的方法)、Procs(类似于绑定(bind)到执行上下文的 block ,即使在传递时它们也会保留)和 Lambdas可能最接近匿名函数。我不会在这里详细介绍 Procs 与 Lambdas。
以下是 Ruby 中这些构造的示例:
# Using a block + yield
def my_method(arg)
puts arg + yield(3)
end
my_method(5) { |arg| arg * 2 }
# => 11
# Binding the block to a Proc then using #call
def print(&block)
puts block.call
end
# Creating a Proc that can be passed around and then #called
def other_method(arg, other_args*)
arg.call(other_args*)
end
var = 3
prc = Proc.new { puts var }
other_method(prc)
# Creating a Lambda using stabby syntax
num = 3
l = -> (arg) { arg + 2 + num }
other_method(l, 1)
在 Ruby 中,您可以将 JS 示例编写为:
def outer(input)
closure_var = "I'm here with "
inner = -> { closure_var + input }
inner.call
end
outer('outer input')
在 IRB 中:
jbodah@Joshs-MacBook-Pro-2 2.1.3p242 ~ (none) $ irb
irb(main):001:0> def outer(input)
irb(main):002:1> closure_var = "I'm here with "
irb(main):003:1>
irb(main):004:1* inner = -> { closure_var + input }
irb(main):005:1>
irb(main):006:1* inner.call
irb(main):007:1> end
=> :outer
irb(main):008:0>
irb(main):009:0* outer('outer input')
=> "I'm here with outer input"
关于javascript - 在 Ruby 中实现类似 JavaScript 的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34891153/