40

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

class Outerclass
  def foobar
    puts "FOOBAR"
  end

  class Innerclass   
    def barfoo
      puts "BARFOO"
    end
  end
end

这是我在 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]

以下是我的问题:

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

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

  3. 一般来说,您希望在类中拥有类的一些原因是什么?这样做有什么好处吗?

  4. Outerclass 的实例是否知道有关 Innerclass 的任何信息?

  5. Innerclass 的实例是否知道有关 Outerclass 的任何信息?

感谢您提供的任何帮助!

4

2 回答 2

55

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

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

  InnerClass = Class.new do   
    def barfoo
      puts "BARFOO"
    end
  end
end

因此,当 Ruby 遇到嵌套类时,它会将其InnerClass分配给分配给常量的常量,OuterClass 它们彼此之间没有任何关系。

InnerClass没有继承OuterClass到:

  InnerClass.ancestors
  => [InnerClass, Object, Kernel, BasicObject]

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

一本关于这方面的好书是“Metaprogramming Ruby”。它详细介绍了类、单例、模块等。

于 2013-02-06T22:53:54.353 回答
0

Jörg W Mittag 在他对 Michael Papile 回答的评论中说得最好:

没有内部和外部类。只有两个完全不相关的类。一个恰好被分配给另一个内部命名空间的常量。

于 2021-04-05T02:32:18.043 回答