转自船长日志, 本文链接地址: http://www.cslog.cn/Content/ruby-deep-clone/
用Ruby复制一个对象(object)也许没有你想像的那么容易. 今天我google了半天, 做个总结吧.
先从最简单的开始, b = a 是复制吗? 看代码说话:
>> a= [0,[1,2]]
>> b=a
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [88, [99, 2]]
从上面代码发现, 一但修改b, 原来的a也同时被改变了. 甚至:
>> b.equal?(a)
=> true
原来b跟a根本就是同一个object, 只是马甲不一样罢了. 所以b = a不是复制.
那 b = a.dup呢?? 还是看代码:
>> a= [0,[1,2]]
>> b=a.dup
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情况似乎有所好转, 在修改b后, a还是有一部分被修改了.(0没有变,但原来的1变成了99).
所以dup有时候是复制(如在Array只有一级时), 但有时不是复制哦.
再来一个, b = a.clone呢? 上代码:
>> a= [0,[1,2]]
>> b=a.clone
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情况几乎跟dup一模一样. 所以clone也不一定可以相信哦!
原来ruby中的dup和clone都是shallow复制, 只针对object的第一级属性.
汗, 难道在Ruby中没有办法复制对像吗? 也不完全是, 看这个:
>> a= [0,[1,2]]
>> b=Marshal.load(Marshal.dump(a))
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a= [0,[1,2]]
=> [0, [1, 2]]
修改b后a没有被改变!!! 似乎终于成功找到复制的办法了!!!
为什么要加"似乎"呢? 因为有些object是不能被Marshal.dump的.如:
>> t=Object.new
>> def t.test; puts ‘test’ end
>> Marshal.dump(t)
TypeError: singleton can’t be dumped
from (irb):59:in `dump’
from (irb):59
更完善的复制方案可以考虑给ruby增加一个deep clone功能, 可以参考以下链接:
http://d.hatena.ne.jp/pegacorn/20070417/1176817721
http://www.artima.com/forums/flat.jsp?forum=123&thread=40913
好了, 复制这个小问题, 没想到也能引出这么长的文章来, 没想到吧?
分享到:
相关推荐
使用fork、exit和exec系统调用编写多进程程序
}3.、控制台,可以看到了改了复制出来的,也不会改变之前的4、浅复制 对象中引入对象,观察浅复制和深复制的区别理解:1、浅复制中加入对象,测试观察引出深复制2、
twitter-clone, 一种基于 Ruby on Rails的Twitter 开源克隆 twitter克隆使用 Ruby on Rails http://twitter-clone-rails.herokuapp.com/的Twitter的开源克隆。正在启动git clone https://github.co
安装 gem install ruby_deep_clone或将其添加到您的Gemfile gem 'ruby_deep_clone'并运行bundle install用法可以如下使用: require 'deep_clone'object = Object.newclone_object = DeepClone.clone obj
主要介绍了Java 数组复制clone方法实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Java Clone(类的复制)实例代码 Java Clone(类的复制)实例代码
微狗硬复制工具,查狗、读狗、写狗,密码清除。希望使用者发表经验,相互交流
下面小编就为大家带来一篇深入理解JavaScript中的对象复制(Object Clone)。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
git clone 最新版 不多说上资源 好用测试ok git clong git clone 最新版 不多说上资源 好用测试ok git clong
List的深度复制 浅谈C#中List<T>对象的深度拷贝问题
NULL 博文链接:https://zzqrj.iteye.com/blog/572562
主要介绍了php5对象复制、clone、浅复制与深复制,结合实例形式详细分析了php5对象复制、clone、浅复制与深复制相关概念、原理、使用技巧与操作注意事项,需要的朋友可以参考下
Clone 属性的相关内容 Clone 属性的相关内容
在使用高版本版KEIL时,提示要升级固件,升级后就出现JLINK is Clone的提示!“the emulator is JLink-Clone, the segger software only support orginal segger device” 然后闪退,IDE崩溃关闭! 解决方案: 1....
Darts-clone.rb是的Ruby绑定。 安装 将此行添加到您的应用程序的Gemfile中: gem 'dartsclone' 然后执行: $ bundle install 或将其自己安装为: $ gem install dartsclone 用法 require 'dartsclone' da = ...
支持多个git库clone,提交等常用操作,用户需要根据实际情况微调参数
Clone10-EX-LV2
Jlink-clone解决办法,替换文件
深化理解JavaScript中的对象复制(Object Clone)_.docx
Minesweeper CLone 0.97 Saolei.net扫雷网,小门汉化 Men Shiyun Mine.exe 请自行下载MinesweeperClone_0.97.exe安装后使用