2017-04-04 6 views
1

Ich habe diese Klasse:Ruby initializer

class PriceChange 
    attr_accessor :distributor_id, :product_id, :value, :price_changed_at, :realm 

    def initialize(data = {}) 
    @distributor_id = data[:distributor_id] 
    @product_id  = data[:product_id] 
    @value   = data[:value] 
    @price_changed_at = data[:price_changed_at] 
    @realm   = data[:realm] 
    end 
end 

Und ich möchte die Zuordnung innerhalb der Methode Körper zu vermeiden. Ich möchte eine transparente und elegante Möglichkeit, die Instanzattributwerte festzulegen. Ich weiß, ich kann die Datenschlüssel durchlaufen und etwas wie define_method verwenden. Ich will das nicht. Ich möchte das auf eine saubere Art und Weise tun.

Antwort

1

Ich möchte dies auf eine saubere Art und Weise tun.

Sie erhalten keine attr_accessor s und Instanzvariablen, ohne sie zu definieren. Die unten wird mit einigen einfachen metaprogramming (macht es für "clean" qualifizieren?)

class PriceChange 
    def initialize(data = {}) 
    data.each_pair do |key, value| 
     instance_variable_set("@#{key}", value) 
     self.class.instance_eval { attr_accessor key.to_sym } 
    end 
    end 
end 

Verbrauch:

price_change = PriceChange.new(foo: :foo, bar: :bar) 
#=> #<PriceChange:0x007fb3a1755178 @bar=:bar, @foo=:foo> 
price_change.foo 
#=> :foo 
price_change.foo = :baz 
#=> :baz 
price_change.foo 
#=> :baz 
+0

Ihr Code ist zweifellos sehr sauber, aber, wie ich sagte: „Ich weiß, dass ich kann die Datenschlüssel durchlaufen und etwas wie define_method verwenden ". Ich suche nach einem "transparenten" Weg. Vielleicht existiert es nicht. – Leantraxxx

+1

@Leantraxxx es existiert nicht, AFAICT –

Verwandte Themen