ruby - 实例变量在 'dup'之后仍然引用

标签 ruby dup

我有一个类的对象,我想用dup 复制它。其中一个实例变量是一个数组,它似乎在引用它。我认为 dup 实际上创建了一个 DUPLICATE。

这是我的 IRB session :

irb(main):094:0> class G
irb(main):095:1> attr_accessor :iv
irb(main):096:1> def initialize
irb(main):097:2> @iv = [1,2,3]
irb(main):098:2> end
irb(main):099:1> end
=> nil

irb(main):100:0> a=G.new
=> #<G:0x27331f8 @iv=[1, 2, 3]>

irb(main):101:0> b=a.dup
=> #<G:0x20e4730 @iv=[1, 2, 3]>

irb(main):103:0> b.iv<<4
=> [1, 2, 3, 4]
irb(main):104:0> a
=> #<G:0x27331f8 @iv=[1, 2, 3, 4]

我希望 a 保持不变,因为 dup 创建了一个全新的变量,而不是引用。

另请注意,如果您要将 [1,2,3] 替换为 G::initialize 中的标量,dup 将不引用它。

最佳答案

dupclone 的默认实现只是进行浅拷贝,因此您将有两个对象引用同一个数组。要获得所需的行为,您应该定义一个 initialize_copy 函数(由 dupclone 调用):

class G
  attr_accessor :iv
  def initialize_copy(source)
    super
    @iv = source.iv.dup
  end
end

那么这两个对象就会引用两个不同的数组。如果数组中包含可变对象,您可能想要更深入地dup数组中的每个对象:

def initialize_copy(source)
  super
  @iv = source.iv.collect &:dup
end

关于ruby - 实例变量在 'dup'之后仍然引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8691496/

相关文章:

ruby - Chef : cannot load such file -- moneta/basic_file

ruby - 在 Ruby 数组 Enumerable Enumerator 中查找上一个元素

ruby - 在 Ruby 中什么时候使用 dup,什么时候使用 clone?

c - 将文件读入解析器的标准

关于 dup() 用法的困惑

c - 打开描述符和关闭,为什么重要?

ruby-on-rails - Ruby on Rails 短信发送

ruby-on-rails - 如何在没有模板的情况下使用 Rails 发送邮件?

ruby - 部署到 heroku 的 Watir 应用程序

Ruby 递归复制/克隆