我正在研究技术图纸(svg/ruby)的解决方案。我想操纵矩形,并有一个add!
这个类中的方法:
class Rect
def add!(delta)
@x1+=delta
... # and so on
self
end
end
我还需要一个add
方法返回一个Rect
,但不操纵self
:
def add(delta)
r=self.dup/clone/"copy" # <-- not realy the 3 and no quotes, just in text here
r.add! delta
end
dup
and clone
不要做我的事,但是:
def copy; Marshal.load(Marshal.dump(self)); end
does.
为什么普通 Ruby 中不存在这样的基本功能?请不要告诉我我可以逆转add
and add!
, 让add
做这项工作,并且add!
调用它。
我不确定为什么 Ruby 中没有深度复制方法,但我会尝试根据我能找到的信息做出有根据的猜测(请参阅该行下面的链接和引用)。
从这些信息来看,我只能推断Ruby没有深复制方法的原因是因为它很少有必要,并且在真正有必要的少数情况下,还有其他相对简单的方法来完成相同的任务:
正如您已经知道的,使用Marshal.dump
and Marshal.load
目前推荐的方法是执行此操作。这也是《Programming Ruby》推荐的方法(请参阅下面的摘录)。
或者,在这些 gem 中至少可以找到 3 个可用的实现:deep_cloneable http://rubygems.org/gems/deep_cloneable, deep_clone http://rubygems.org/gems/deep_clone and ruby_deep_clone http://rubygems.org/gems/ruby_deep_clone;第一个是最受欢迎的。
相关信息
Here's comp.lang.ruby 上的讨论 https://groups.google.com/forum/#!topic/comp.lang.ruby/iiQialTnnSQ这可能会对此有所启发。有另一个答案在这里 https://groups.google.com/d/msg/comp.lang.ruby/VQXB5mJC4lU/EVb7omQ5jj0J以及一些相关的讨论,但这一切都回到了使用Marshal
.
没有提到深度复制红宝石编程 http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0,但其中有一些提到Ruby 编程语言 https://rads.stackoverflow.com/amzn/click/com/B0026OR3JO。以下是一些相关摘录:
[…]
另一个用途是Marshal.dump
and Marshal.load
是创建深拷贝
对象数量:
def deepcopy(o)
Marshal.load(Marshal.dump(o))
end
[…]
…使用的二进制格式Marshal.dump
and Marshal.load
是
版本相关,并且不保证较新版本的 Ruby
能够读取旧版本 Ruby 编写的编组对象。
[…]
请注意文件和 I/O 流以及方法和绑定
对象太动态而无法编组;就不会有可靠的
恢复其状态的方法。
[…]
无需制作数组的防御性深层副本,只需调用to_enum
其上,并传递结果枚举器而不是数组
本身。实际上,您正在创建一个可枚举但不可变的代理
数组的对象。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)