4

あるオブジェクトから別のオブジェクトに一連のインスタンス変数を追加するにはどうすればよいですか?

たとえば、ベースロボットがあり、アドオンを使用してカスタマイズできるロボットを想像してみてください。

クラスロボット

   def initialize
      @name="シンプルなロボット"
      @power = nil #no power
      @speed = nil
      #その他の属性
   終わり

   def add_attributes(addon)
      @power = addon.power
      @speed = addon.speed
      #アドオンが持つ残りの属性
   終わり
終わり

メソッドを書き直してadd_attributes、アドオンの各属性を1つずつ書き込むのではなく、単純に反復処理したいと思います。これは、数十の属性が存在する可能性があるためです。

一部のアドオンには、Robotにはないインスタンス変数が含まれている場合があります。また、それらをRobotに追加したいと思います。その場でインスタンス変数を作成するのが好きですか?

4

3 に答える 3

8

それはあなたが「属性」によって何を意味するかによります。Rubyにはその概念が直接ありませんが、インスタンス変数をあるオブジェクトから別のオブジェクトにコピーすることができます。

def add_attributes(addon)
  addon.instance_variables.each do |x|
    self.instance_variable_set(addon.instance_variable_get(x))
  end      
end

[編集] @HolgerJustによる回答も良い解決策であることに注意してください。

于 2012-05-09T23:21:33.460 に答える
6

インスタンス変数を取り除き、代わりに単一のハッシュを使用することができます。これには、無料の列挙子と、ロボットが持つすべての機能に1つの便利な場所からアクセスするためのクリーンなインターフェイスという利点があります。

また、インスタンスの内部変数をいじる必要がなくなります。それらは通常、内部であることが意図されており、膨大な量のものに使用されます。機能を公開したい場合は、パブリックメソッドを使用して行う必要があります。内部状態をいじることは、少なくとも悪い設計であり、おそらく後で多くの悲しみにつながるでしょう。一般に、可能な限りメタプログラミングを避けるのが最善です。

class Robot
  attr_reader :features

  def initialize
    @features = {}
    @features[:name] = "simple robot"
    @features[:power] = nil #no power
    @features[:speed] = nil
  end

  def add_attributes(addon)
    @features.merge! addon.features
  end
end
于 2012-05-09T23:25:56.147 に答える
0

多くのコードを記述せずにその場でインスタンス変数を作成できる柔軟なgem[0]を使用できます。ただやる

class SomeClass
  include Flexible
end
sc = SomeClass.new
sc.my_variable_name = 1 # or any other value

[0] https://github.com/matthiasbeyer/flexible

于 2012-05-13T15:12:07.057 に答える