Jör*_*tag 161
更新:由于这个答案最近似乎引起了一些兴趣,我想指出有关Ruby问题跟踪器的讨论要删除这里讨论的功能,即禁止在方法体内部进行方法定义.
不,Ruby没有嵌套方法.
你可以这样做:
class Test1
  def meth1
    def meth2
      puts "Yay"
    end
    meth2
  end
end
Test1.new.meth1
但这不是嵌套方法.我再说一遍:Ruby 没有嵌套方法.
这是一个动态方法定义.当你跑步时meth1,meth1将会执行尸体.正好恰好定义了一个名为的方法meth2,这就是为什么在运行meth1一次之后,你可以调用meth2.
但在哪里meth2定义?好吧,它显然没有被定义为嵌套方法,因为Ruby 中没有嵌套方法.它被定义为以下的实例方法Test1:
Test1.new.meth2
# Yay
此外,每次运行时显然都会重新定义meth1:
Test1.new.meth1
# Yay
Test1.new.meth1
# test1.rb:3: warning: method redefined; discarding old meth2
# test1.rb:3: warning: previous definition of meth2 was here
# Yay
简而言之:不,Ruby 不支持嵌套方法.
另请注意,在Ruby中,方法体不能是闭包,只能是块体.这几乎消除了嵌套方法的主要用途的情况下,因为即使当 Ruby的支持嵌套的方法,你不能在嵌套方法使用外部方法的变量.
更新继续:在稍后阶段,这个语法可能会被重新用于向Ruby添加嵌套方法,这将按照我描述的方式运行:它们将作用于其包含方法,即在其包含方法之外不可见和不可访问身体.并且可能,他们可以访问其包含方法的词法范围.但是,如果您阅读我上面链接的讨论,您可以观察到matz严重违反嵌套方法(但仍然用于删除嵌套方法定义).
Sup*_*ver 12
实际上这是可能的.你可以使用procs/lambda.
def test(value)
  inner = ->() {
    value * value
  }
  inner.call()
end
不,不,Ruby确实具有嵌套方法。检查一下:
def outer_method(arg)
    outer_variable = "y"
    inner_method = lambda {
      puts arg
      puts outer_variable
    }
    inner_method[]
end
outer_method "x" # prints "x", "y"