2016-11-08 20 views
1

我有一個Ruby對象說紅寶石複製對象與修改PARAMS

def initialize(args={}) 
    @name = args[:name] 
    ... 
end 

my_cat = Cat.new(name: 'Mittenz', age: 3, type: 'cheshire') 

我需要另一個對象內,但有一個選項,輸入不同的參數,服用點這樣重複它:

Class CatCopyist 
    def initialize(args={}) 
    @my_cat = args[:cat] # my_cat object from above passed here 
    end 

    def copy_cat 
    another_cat = @my_cat.dup.merge(type: 'siamese') 
    return another_cat 
    end 
    ... 
end 

我需要將複製對象與新參數混合的幫助。

+0

什麼是@ my_cat?你可以發佈實際工作代碼(複製部分除外)嗎? – Max

+0

這是一個錯字。糾正。工作代碼除了變量名外,看起來完全一樣。 –

回答

1

您可以使用Object#instance_variable_set覆蓋舊的變量。

class Cat 
    attr_reader :name, :type, :age 
    def initialize(args={}) 
    @name = args[:name] 
    @age = args[:age] 
    @type = args[:type] 
    end 

    def to_s 
    "#{name} (#{type} - #{age})" 
    end 

    def dup(args={}) 
    new_cat = super() 
    args.each do|var, value| 
     new_cat.instance_variable_set(:"@#{var}", value) 
    end 
    new_cat 
    end 
end 
mittenz = Cat.new(name: 'Mittenz', age: 3, type: 'cheshire') 

puts mittenz 
puts mittenz.dup(type: 'siamese') 
#=> Mittenz (cheshire - 3) 
# Mittenz (siamese - 3) 
+0

看起來像解決了我的問題,所以我將停止在這個答案,謝謝! –

+0

':'是不必要的。 'instance_variable_set'接受一個字符串或一個符號。 – Max

+0

兩者都很好,是的。來自doc:「如果實例變量名稱作爲字符串傳遞,則該字符串將轉換爲符號。」我不妨直接發送一個符號。 –

0

您可以覆蓋DUP方法來定義您的自定義行爲

def dup(args = {}) 
    d = super() 
    args.each do |k, v| 
    d.send(:"#{k}=", v) 
    end 
    d 
end 
+0

你不能確定setter是否被定義,你能嗎? –

+0

如果沒有定義setter,你可以使用'd.instance_variable_set(「@#{k}」,v)' –