Chienomi

Rubyのサブクラス内のスーパークラスのネストされたクラス

プログラミング

  • TOP
  • Old Archives
  • Rubyのサブクラス内のスーパークラスのネストされたクラス

意味が分からないと思うが、ちょっとした疑問だ。

class A
  class B
  end
end

Class AA < A
  B
end

このコードではAAの中のBA::Bになる。 つまり、AAのコンテキストの中でBは使用可能だ。

class A
  class B
    def hi
      puts "Hi"
    end
  end
end

class AA < A
  class B
    def hihi
      puts "HiHi"
    end
  end
  
  def initialize
    @b = B.new
  end
  
  def b
    @b.hi
    @b.hihi
  end
end

aa = AA.new
aa.b

このコードでは

class AA
  class B
  end
end

AA::Bが作られ、@b#hiがないためエラーとなる。

class A
  class B
    def hi
      puts "Hi"
    end
  end
end

class AA < A
  class B < B
    def hihi
      puts "HiHi"
    end
  end
  
  def initialize
    @b = B.new
  end
  
  def b
    @b.hi
    @b.hihi
  end
end

aa = AA.new
aa.b

この場合は、

class B < B

によって、A::BをスーパークラスとするサブクラスAA::Bが作られる。

この定義によってBという名前がオーバーライドされることとなる。

class A
  class B
    def hi
      puts "Hi"
    end
  end
end

class AA < A
  B = B
  class B
    def hihi
      puts "HiHi"
    end
  end
  
  def initialize
    @b = B.new
  end
  
  def b
    @b.hi
    @b.hihi
  end
end

aa = AA.new
aa.b

これが本来意図するところだ。 オープンクラスを用いてスーパークラス内で定義されたクラスを拡張したいのだろう。

そこで

B = B

によって

AA::B = A::B

とした上でクラスを開けば良いのだ。

だが、今回の場合はPureDocのために実験した。PureDocではサブクラス内での#instance_evalによって評価された時に呼ばれるメソッドが名前でこのクラスのインスタンスを生成するため、あくまでもサブクラス(AA相当)の中に閉じ込められたクラス(B)でしかない。

ということは、そのクラスは

AA::B = A::B

ではなく

AA::B < A::B

であることが本来望ましいのではないだろうか。