2016-11-08 16 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)' –