了解Ruby嵌套函数

时间:2014-02-10 08:46:34

标签: ruby closures

我正在学习红宝石。我试图了解闭包的工作方式,以及它们与函数的区别。 我完全清楚应该通过proc或lambda 实现闭包。

我正在努力深入了解红宝石。因此,我检查各种非正统的代码。我试图理解为什么第3行工作而第5行是错误。

x=123
def b(x)
    p x
    def a(u)
      p x # why is this an error?!?!?
    end
    a 4
end

b 1
  1. 如果a无法访问b的参数,为什么不访问全局x = 123?
  2. 如果我明确使用更改行1& 5到全球“$ x”?
  3. 如果我明确使用lambda,为什么会这样?
  4. 这纯粹是一个学习练习,我这样做是为了了解幕后发生的事情。

2 个答案:

答案 0 :(得分:4)

这就是所谓的“范围门”。基本上,当您开始定义方法/类/模块时,会创建一个新范围,并且无法访问其他范围内的所有局部变量。这不适用于实例/全局变量,您将继续访问这些变量。

由于lambda不是方法,因此它不会创建新范围并重新使用现有范围。

另外,

  

为什么第3行工作

x = 123
def b(x)
    p x # this "x" is "x the parameter", not "x the local variable from outer scope"
        # that's why it works. If you tried to access the local var, it wouldn't work.
    def a(u)
      p x # like here, see? Doesn't work.
    end
    a 4
end

b 1

答案 1 :(得分:3)

要理解的第一件事是def没有创建“函数”(这在Ruby中甚至意味着什么?) - def定义了一个方法一些对象或类。即使它看起来不在任何对象内,它仍然在“主”对象上定义一个方法。因此,当您执行def a时,它不是方法b的“本地”;它是一个方法a,就像你在顶级定义它一样,除了它在b运行之前不会被定义。它可以从其他地方称为方法a。您有嵌套方法定义

因为它是为了定义方法,大部分时间是在类或模块的顶层定义的,所以def从未被用来捕获外部变量。