捕获 Ruby 方法中的变量

2023-11-25

在咖啡脚本中:

f = ->
  v = 5
  g = ->
    v
  g()

f() # returns 5 as expected

In Ruby:

def f
  v = 5
  def g
    v # undefined local variable or method `v' for main:Object (NameError)
  end
  g
end
f

好吧,显然 JavaScript 函数被设置为捕获它们创建的范围内的变量,但 Ruby 的方法却不是。在这方面有没有办法让 Ruby 方法表现得像 JavaScript 函数?


Ruby 具有脚本作用域、模块/类/方法定义作用域和块作用域。只有块才能创建嵌套范围。因此,您需要使用块来定义您的方法。值得庆幸的是,有一种方法可以定义需要块的方法:

def f
  v = 5
  define_method :g do
    v
  end
  g
end
f
# => 5

但是,请注意,这确实not做你认为它会做的事(你的原始代码也不做)。确实如此not定义一个方法g嵌套在方法中f。 Ruby 没有嵌套方法。方法总是属于模块(类是模块),它们不能属于方法。

它的作用是定义一个方法f,当你运行它时它定义了一个方法g然后调用该方法。

Observe:

methods.include?(:g)
# => true

您现在已经定义了一个新的顶级方法(实际上是Object)称为g,并且每次你都会一遍又一遍地定义它f被叫。

您可能想要的是 lambda:

def f
  v = 5
  g = -> { v }
  g.()
end
f
# => 5

在对另一个答案的评论中,您写道:

好吧,我正在摆弄 lambda,我注意到我所做的任何事情v代替g没有体现在v once g返回。有什么方法可以让我做出改变v stick?

def f
  v = 5
  g = -> { v = 'Hello' }
  g.()
  v
end
f
# => 'Hello'

如您所见,更改为v does“粘”后g返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

捕获 Ruby 方法中的变量 的相关文章