Ruby中复制对象的几种方法
Ruby内置的方法Object#clone和Object#dup可以用来copy一个对象,两者区别是dup只复制对象的内容,而clone还复制与对象相关联的内容,如singleton method
s = "cat" def s.upcase "CaT" end s_dup = s.dup s_clone = s.clone s_dup.upcase #=> "CAT" (singleton method not copied) s_clone.upcase #=> "CaT" (uses singleton method)
dup和clone都是浅复制Shallow Copy,也就是只能复制接受方的内容,而如果接受方包含到其他对象的引用,那么就只是会复制这些引用了。
arr1 = [ 1, "flipper", 3 ] arr2 = arr1.dup arr2[2] = 99 arr2[1][2] = 'a' arr1 #=> [1, "flapper", 3] arr2 #=> [1, "flapper", 99]
可以看到arr1中有一个到String对象的引用,从而arr2也复制了这个引用,当arr2中修改这个引用时,arr1中的也会发生变化。
如果要进行深复制Deep Copy,可以聪明的采用Marshal模块
arr1 = [ 1, "flipper", 3 ] arr2 = Marshal.load(Marshal.dump(arr1)) arr2[2] = 99 arr2[1][2] = 'a' arr1 #=> [1, "flipper", 3] arr2 #=> [1, "flapper", 99]
现在就会发现arr2中对String对象的修改不会导致arr1的变化了,因为深了。。。不过Marshal模块并不能把所有的对象都序列化
在class中还有一个与对象复制相关的特殊方法initialize_copy,这个方法会在信息复制完成后执行,看下面这个示例
class Document attr_accessor :title, :text attr_reader :timestamp def initialize(title, text) @title, @text = title, text @timestamp = Time.now end end doc1 = Document.new("Random Stuff", "Haha") sleep 10 doc2 = doc1.clone doc1.timestamp == doc2.timestamp #=> true
也就是两个对象是完全一样的,构造函数initialize被跳过了,所以两个对象的时间戮timestamp是相同的。如果要采用执行复制操作时的时间,我们可以通过给Document类添加initialize_copy方法来实现。initialize_copy让程序员能完全控制对象复制的状态
class Document #Reopen the class def initialize_copy(other) @timestamp = Time.now end end doc3 = Document.new("More Stuff", "Haha") sleep 10 doc4 = doc1.clone doc3.timestamp == doc4.timestamp #=> false
再次感慨Ruby的魅力。。。
PS:以上内容主要来自The Ruby Way
本文基于 署名-非商业性使用-禁止演绎 2.5 中国大陆 发布
10 COMMENTS >>LEAVE<<
-
嗯嗯,先把事情忙完,一定搞搞Ruby
-
还没看ruby,不懂.看到一个有趣的东东-tiddlywiki
-
@happybabe
TiddlyWiki是个非常小巧酷炫的wiki引擎,全部程序只是一个一百多K的HTML页面。TiddlyWiki用CSS+HTML+javascript写成,可以在多种浏览器上浏览。。。
只有个html能做什么啊。。。
-
@ABitNo
可以当记事本,可以当本地wiki,直接上传到免费空间就是个站点.不分后台前端,不用数据库,可随身携带,有一定量插件和主题.我想把它当本地wiki用,windows,linux通用,看效果怎么样.本来想用mediawiki,不过需要php环境,备份数据库很麻烦.
-
@ABitNo
夜猫子也起早了?Arch wiki也是Powered by mediawiki.Arch wiki实在是太好,没有它估计我现在都无法入门linux.Ubuntu wiki看完一头雾水,茫然无措.
-
好复杂的东西。编程= = 我从来记不住代码。连VB的几乎都忘了。。
-
@happybabe
这今天起早去爬山了,爬了一天,累死了,而且还下了大雨。。。
-
@数数
yi哈哈。。。个人爱好而已。。。
我就是喜欢这些东西,除了这也没什么会的了。。。 -
没电脑,好闷好寂寞.用手机上来打个招呼,睡觉喽~