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. ルビーインタープリターが上記のクラス定義コードに最初に遭遇したとき、それは私が書いたメソッドを通過し、それをどこかに保存しますか?Outerclass定義内でインスタンスメソッドが呼び出されないため、インスタンスメソッド「foobar」は実際には実行されないことを知っています。

  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定数を呼び出すと、割り当てられた Class.new ステートメントに等しいInnerClass定数の下で名前空間化された定数を参照しています。OuterClass

これについて読むのに良い本は「Metaprogramming Ruby」です。クラス、シングルトン、モジュールなどの詳細に入ります。

于 2013-02-06T22:53:54.353 に答える