7
module A; def a; end; end
module B; def b; end; end

class C; include A; end

module A; include B; end
class D; include A; end

C.new.b # undefined method error
D.new.b # nil

C.ancestors # [C, A, Object...]
D.ancestors # [D, A, B, Object...]

モジュールBをA内に含めて、すでにモジュールAが含まれているクラスが、モジュールBからもメソッドを取得するようにするにはどうすればよいですか?

4

3 に答える 3

3

すでに述べたように、Rubyはこのようには機能しません-クラスにモジュールが含まれている場合、そのモジュールのインスタンスへの参照は維持されないため、モジュールに他のモジュールが含まれている場合、すでに含まれているクラスが勝ちます変更についてはわかりません。

これを回避するには、モジュールを含むクラスをモジュール自体に格納します。これにより、モジュールに別のモジュールが含まれるたびにそれらを更新できます。つまり、次のようになります。

module A

  class<<self
    attr_accessor :observers
  end

  self.observers = []

  def a
    "#{self} successfully called a"
  end

  def self.included(base)
    self.observers << base unless self.observers.include?(base)
  end

  def self.include(mod)
    observers.each {|o| o.send(:include,mod) }
    super
  end

end

module B
  def b
    "#{self} successfully called b"
  end
end

class C
  include A
end

module A
  include B
end

class D
  include A
end

module E
  def e
    "#{self} successfully called e"
  end
end

module A
  include E
end

puts C.new.b 
puts D.new.b 
puts C.new.e
puts D.new.e

これがあなたが取りたい方向であるかどうかはわかりませんが、原則としてそれが可能であることを示しています。

于 2012-12-19T14:17:56.417 に答える
2

できません。

クラスにミックスインすると、includeRubyは、メソッドテーブルがミックスインのメソッドテーブルを指し、スーパークラスがのスーパークラスである新しいクラスを作成し、このクラスをの新しいスーパークラスにします。これは、にミックスされたすべてのミックスインに対して繰り返されます。MC⟦M′⟧MCCM

Mに混合すると、このアルゴリズムは1回だけ実行されることに注意してくださいC。後でdを取得するモジュールはinclude、考慮されません。

于 2012-07-16T12:08:48.957 に答える
1

クラスCの前にBをAに含める必要があります 。Aを含む; 終了

module A; def a; end; end
module B; def b; end; end


module A; include B; end

class C; include A; end
class D; include A; end

p C.new.b # nil
p D.new.b # nil

p C.ancestors # [C, A, B, Object, Kernel, BasicObject]
p D.ancestors # [D, A, B, Object, Kernel, BasicObject]

編集

module A; def a; end; end
module B; def b; end; end

class C; include A; end

module A; include B; end
class D; include A; end

C.send(:include, A)

p C.new.b # nil
p D.new.b # nil

p  C.ancestors # [C, A, Object...]
p D.ancestors # [D, A, B, Object...]
于 2012-07-16T11:37:15.827 に答える