为什么Ruby中没有深度复制方法? [英] Why isn't there a deep copy method in Ruby?

查看:180
本文介绍了为什么Ruby中没有深度复制方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个技术图纸(svg / ruby​​)的解决方案。我想操作矩形,并在此类中有 add!方法:

  class Rect 
def add!(delta)
@ x1 + = delta
...#等等
self
end
end



我还需要一个 add code> Rect ,但不操作 self

  def add(delta)
r = self.dup / clone /copy#< - 不是真的3和没有引号,只是在这里的文本
r.add! delta
end

dup clone 不要做我的事,但

  Marshal.load(Marshal.dump(self));结束



一个基本的功能不存在于普通的Ruby?请不要告诉我可以转换添加 add!,让 add 执行该作业,并添加!调用它。

解决方案

我不知道为什么Ruby中没有深度复制方法,但我会尝试根据我可以找到的信息做一个有根据的猜测(参见下面的链接和引号)。



根据这些信息,我只能推断Ruby没有深层复制方法的原因是因为它很少是必要的,在真正有必要的少数情况下,是其他相对简单的方法来完成相同的任务:



如你所知,使用 Marshal.dump Marshal.load 是目前推荐的方法。这也是编程Ruby推荐的方法(见下面摘录)。



或者,这些gem中至少有3个可用的实现: deep_cloneable deep_clone ruby​​_deep_clone





以下是在comp.lang的讨论.ruby 这可能会淡化一些光。有这里的另一个答案和一些相关的讨论,但它所有回到使用 Marshal



没有提到深度复制编程Ruby ,但在 Ruby编程语言。以下是几个相关的摘录:



Marshal.dump Marshal.load 是创建对象的深度副本

  def deepcopy(o)
Marshal.load(Marshal.dump(o))
end



[...]



... Marshal.dump Marshal.load
版本相关的,新版本的Ruby不保证是
能读取旧版本的Ruby编写的编组对象。



[...]



文件和I / O流,以及方法和绑定
对象,太动态,无法编组;将不会有可靠的
方式恢复其状态。



[...]



做一个防御深复制的数组,只需调用
to_enum 就可以了,并传递生成的枚举,而不是数组
本身。实际上,您为数组创建了一个可枚举但不可变的代理
对象。



I am working on a solution for technical drawings (svg/ruby). I want to manipulate rectangles, and have an add! method in this class:

class Rect
  def add!(delta)
    @x1+=delta 
    ... # and so on
    self
  end
end

I also need an add method returning a Rect, but not manipulating 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 don't do my thing but:

def copy; Marshal.load(Marshal.dump(self)); end

does.

Why does such a basic functionality not exist in plain Ruby? Please just don't tell me that I could reverse add and add!, letting add do the job, and add! calling it.

解决方案

I'm not sure why there's no deep copy method in Ruby, but I'll try to make an educated guess based on the information I could find (see links and quotes below the line).

Judging from this information, I could only infer that the reason Ruby does not have a deep copy method is because it's very rarely necessary and, in the few cases where it truly is necessary, there are other, relatively simple ways to accomplish the same task:

As you already know, using Marshal.dump and Marshal.load is currently the recommended way to do this. This is also the approach recommended by Programming Ruby (see excerpts below).

Alternatively, there are at least 3 available implementations found in these gems: deep_cloneable, deep_clone and ruby_deep_clone; the first being the most popular.


Related Information

Here's a discussion over at comp.lang.ruby which might shed some light on this. There's another answer here with some associated discussions, but it all comes back to using Marshal.

There weren't any mentions of deep copying in Programming Ruby, but there were a few mentions in The Ruby Programming Language. Here are a few related excerpts:

[…]

Another use for Marshal.dump and Marshal.load is to create deep copies of objects:

def deepcopy(o)
  Marshal.load(Marshal.dump(o))
end

[…]

… the binary format used by Marshal.dump and Marshal.load is version-dependent, and newer versions of Ruby are not guaranteed to be able to read marshalled objects written by older versions of Ruby.

[…]

Note that files and I/O streams, as well as Method and Binding objects, are too dynamic to be marshalled; there would be no reliable way to restore their state.

[…]

Instead of making a defensive deep copy of the array, just call to_enum on it, and pass the resulting enumerator instead of the array itself. In effect, you’re creating an enumerable but immutable proxy object for your array.

这篇关于为什么Ruby中没有深度复制方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆