2013-07-03 4 views
5

は、私は2つのモジュールがあるとします。今Rubyの動的モジュールミックスイン

module Test1 

    attr_accessor :a, :b 

    @a = 0.0 
    @b = 0.0 

end 

module Test2 

    attr_accessor :c, :d 

    @c = 0.0 
    @d = 0.0 

end 

を、私は条件付きでクラスにこれらのモジュールをミックスしたいです。これは私が試したものです:

obj = MyClass.new(0) 
obj.a #=> nil 

また@aは、クラス内のインスタンスメソッドでnilです:

require './Test1.rb' 
require './Test2.rb' 

class MyClass 

    def initialize(mode) 
    if mode == 0 
     (class << self; include Test1; end) 
    elsif mode == 1 
     (class << self; include Test2; end) 
    else 
     class << self 
     include Test1 
     include Test2 
     end 
    end 
    end 

end 

これは私が見てい動作です。私はここで重要な何かを理解していないと感じています。なぜ私がやっていることが機能していないのか、私の望む機能を達成する正しい方法は何かを理解したいと思います。

答えて

9

モジュールで設定したこれらのインスタンス変数は、MyClassインスタンスに属しているのではなく、モジュール自体に属しているため、この現象が発生します。このコードを考えてみましょう:この問題を解決するために

Test1.instance_variable_get(:@a) 
# => 0.0 

を、あなたはincludeの代わりにextendを使用することもできます。

module Test1 

    attr_accessor :a, :b 

    def self.extended(object) 
    object.a, object.b = 0.0, 0.0 
    end 

end 

module Test2 

    attr_accessor :c, :d 

    def self.extended(object) 
    object.c, object.d = 0.0, 0.0 
    end 

end 

そして、あなたのクラスで:

require './Test1.rb' 
require './Test2.rb' 

class MyClass 

    def initialize(mode) 
    if mode == 0 
     extend Test1 
    elsif mode == 1 
     extend Test2 
    else 
     extend Test1 
     extend Test2 
    end 
    end 

end 
+0

これはまさに私が探していたものです。ありがとう! –

2

私は仕事への道を考えこの問題の周りに、私はそれを共有すると思ったので。私はまだ誰かが私がしようとしているものを達成するためのより良い方法を知っているかどうかを見たいと思う。

Module Test1 
    attr_accessor :a, :b 

    def init1 
    @a = 0.0 
    @b = 0.0 
    end 
end 

class MyClass 
    def initialize 
    if mode == 0 
     (class << self; include Test1; end) 
     init1 
    elsif mode == 1 
     ... 
    end 
end 
関連する問題