类中的Ruby类(或模块中的模块)

wmo*_*ock 39 ruby

当我阅读不同的Ruby书籍时,我注意到Ruby类可以在其他Ruby类或模块中定义.以下是类中类的示例:

class Outerclass
  def foobar
    puts "FOOBAR"
  end

  class Innerclass   
    def barfoo
      puts "BARFOO"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

这是我在IRB中运行的一些代码,试图从概念上理解这一点:

oc = Outerclass.new # => #<Outerclass:0x00000100a46478>

Outerclass.instance_methods(false) # => [:foobar]

ic = Outerclass::Innerclass.new # => #<Outerclass::Innerclass:0x00000100a0b120>

ic = Outerclass::Innerclass.instance_methods(false) # => [:barfoo]
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

  1. 当ruby解释器第一次遇到我上面的类定义代码时,它是否会通过我编写的方法并将其存储在某个地方?我知道实例方法"foobar"实际上并没有运行,因为在Outerclass定义中没有调用它.

  2. 撇开第一个问题,当Ruby遇到类Innerclass时怎么样?这里发生了什么?

  3. 一般来说,为什么你想要在类中有类?这样做有什么好处吗?

  4. Outerclass的实例是否知道有关类Innerclass的任何内容?

  5. Innerclass的一个实例是否知道类Outerclass的任何内容?

感谢您提供的任何帮助!

Mic*_*ile 53

当解释器通过这个文件时,它会分配这样的类:

OuterClass = Class.new do 
  def foobar
    puts "FOOBAR"
  end

  InnerClass = Class.new do   
    def barfoo
      puts "BARFOO"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

因此,当Ruby遇到嵌套类时,它会将它InnerClass分配给常量,该常量被赋予常量.OuterClass 它们彼此之间没有任何关系.

InnerClass没有继承OuterClass:

  InnerClass.ancestors
  => [InnerClass, Object, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)

当您调用OuterClass::InnerClass常量时,您将引用在contstant InnerClass下命名空间的OuterClass常量,该常量等于分配给它的Class.new语句.

阅读这篇文章的好书是"Metaprogramming Ruby".它涉及课程,单身人士,模块等的细节.

  • 更简单地说:没有内在和外在的阶级.只有两个完全无关的课程.一个恰好被分配给另一个内部的常量命名空间.不幸的是,Ruby不支持嵌套类.要了解嵌套类如何工作以及它们与您在此处看到的根本不同,请查看Beta编程语言,该语言引入了嵌套类和使用它们以实现卓越效果的Newspeak编程语言(尤其是其库). (22认同)
  • 是的,除了指向单独内部类的外部类中的常量之外,没有任何事情发生.他们没有继承或共享方法.它们是100%独立的课程. (7认同)
  • 是的,这些现在是2个常量,指的是2个类.但是,InnerClass常量被命名为外部类.如果你移动了内部类,那么除了OuterClass :: Innerclass现在是顶级常量并且OuterClass没有对它的引用之外,它也是相同的. (4认同)