在Ruby 1.9中复制对象和子对象
我的应用程序中有一个在Ruby 1.9中复制对象和子对象,ruby,Ruby,我的应用程序中有一个KillerSudoku类 每个实例在@cells中有许多单元格,在@zones中有许多区域,依此类推 有没有一种方法可以轻松复制一个对象(数独)复制它的所有“子对象”,也就是说,我希望我的副本中有可以修改的单元格和区域,而无需修改以前的数独?假设所有部分都是,并且你想要一个完全深度的克隆: class Object # This doesn't have to be on Object; it could be on KillerSudoku instead def
KillerSudoku
类
每个实例在@cells
中有许多单元格,在@zones
中有许多区域,依此类推
有没有一种方法可以轻松复制一个对象(数独)复制它的所有“子对象”,也就是说,我希望我的副本中有可以修改的单元格和区域,而无需修改以前的数独?假设所有部分都是,并且你想要一个完全深度的克隆:
class Object
# This doesn't have to be on Object; it could be on KillerSudoku instead
def deep_clone
Marshal.load(Marshal.dump(self))
end
end
在行动中看到:
class KillerSudoku
attr_accessor :cells
end
ks1 = KillerSudoku.new
ks1.cells = ["one",2,3]
ks2 = ks1.deep_clone
ks2.cells.pop
ks2.cells.first.reverse!
p ks1.cells, ks2.cells
#=> ["one", 2, 3]
#=> ["eno", 2] # New array with all instance values being uniq, too
ks1 = KillerSudoku.new
ks1.cells = ["one",2,3]
ks2 = ks1.clone
ks2.cells.pop
ks2.cells.first.reverse!
p ks1.cells, ks2.cells
#=> ["eno", 2, 3]
#=> ["eno", 2] # New array that references all the same objects
从文档中可以看出,如果您的结构中存在以下任何一项,则上述内容将不起作用:
- 匿名
或类
模块
- 与系统相关的对象(例如
,Dir
,File::Stat
,IO
,文件
,等等)套接字
,匹配数据
,数据
,方法
,取消绑定方法
,过程
,线程
,线程组
继续
- 定义单例方法的对象
如上所述,这是一个真正的深度克隆,甚至字符串也成为新实例。如果希望克隆单元格和分区的数组,但所有值仍引用相同的对象,则需要使用
初始化\u复制
自定义dup
和克隆
的操作:
class KillerSudoku
attr_accessor :cells
def initialize_copy(old)
self.cells = old.cells.dup
end
end
在行动中看到:
class KillerSudoku
attr_accessor :cells
end
ks1 = KillerSudoku.new
ks1.cells = ["one",2,3]
ks2 = ks1.deep_clone
ks2.cells.pop
ks2.cells.first.reverse!
p ks1.cells, ks2.cells
#=> ["one", 2, 3]
#=> ["eno", 2] # New array with all instance values being uniq, too
ks1 = KillerSudoku.new
ks1.cells = ["one",2,3]
ks2 = ks1.clone
ks2.cells.pop
ks2.cells.first.reverse!
p ks1.cells, ks2.cells
#=> ["eno", 2, 3]
#=> ["eno", 2] # New array that references all the same objects
我添加了一个替代实现,具体取决于您真正想要克隆的深度。有一种观点认为,最好定义
initialize\u copy
方法来实现特定于类的复制行为,而不是覆盖dup
或clone
。它们都会激活initialize\u copy
。下面是关于这个问题的讨论。Marshal::load(Marshal.dump(foo))
可以工作,但可能会导致数据库模型出现问题,因为它们可能会从数据库中重新提取。