私がこのクラスを持っている場合:
class A
attr_accessor :b,:c,:d
end
そしてこのコード:
a = A.new
h = {"b"=>10,"c"=>20,"d"=>30}
各ペアを調べてinstance_variable_set
を呼び出すことなく、ハッシュから直接オブジェクトを初期化することは可能ですか?何かのようなもの:
a = A.new(h)
これにより、各インスタンス変数がハッシュ内で同じ名前を持つものに初期化されます。
クラスで初期化関数を定義できます。
class A
attr_accessor :b,:c,:d
def initialize(h)
h.each {|k,v| public_send("#{k}=",v)}
end
end
または、モジュールを作成してから「ミックスイン」することもできます
module HashConstructed
def initialize(h)
h.each {|k,v| public_send("#{k}=",v)}
end
end
class Foo
include HashConstructed
attr_accessor :foo, :bar
end
または、 コンストラクター のようなものを試すこともできます
OpenStruct
検討する価値があります:
require 'ostruct' # stdlib, no download
the_hash = {"b"=>10, "c"=>20, "d"=>30}
there_you_go = OpenStruct.new(the_hash)
p there_you_go.c #=> 20
instance_variable_set
は、この種のユースケースを対象としています。
class A
def initialize(h)
h.each {|k,v| instance_variable_set("@#{k}",v)}
end
end
これはパブリックメソッドなので、構築後に呼び出すこともできます。
a = A.new({})
a.instance_variable_set(:@foo,1)
ただし、 ドキュメント の暗黙の警告に注意してください。
インスタンス変数名をシンボルごとにオブジェクトに設定します。これにより、クラスの作成者が適切なカプセル化を提供しようとする努力が妨げられます。この呼び出しの前に変数が存在している必要はありませんでした。