javascript - 在 Ruby 中实现类似 JavaScript 的闭包

标签 javascript ruby

我发现在以下模式中不使用闭包很难编程:

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/

相关文章:

ruby - 如何将可汇总指标压缩为 ruby​​ 表中的唯一标识符

ruby - "**/*/"和 "**/"之间的区别?

javascript - 如何允许将 ES5 和 ES6 导入我的 npm 包?

javascript - Jquery 选择器,我应该指定 html 标签的类型吗?

javascript - React UseState - 使用先前的状态与不使用先前的状态

ruby-on-rails - Heroku 上的 Rails 4 错误 R14(超出内存配额)

c# - 这个onload事件有什么问题?

javascript - 想要在鼠标悬停时更改文本

ruby - strftime 数小时内无填充

ruby - 将正文拆分成句子但保留标点符号?