Changing state of Ruby objects changes other class members?

柔情痞子 提交于 2019-12-06 08:51:01

By default, dup and clone produce shallow copies of the objects they are invoked on. Meaning that x and y in your example still reference the same area of memory.

http://ruby-doc.org/core-2.0/Object.html#method-i-dup

http://ruby-doc.org/core-2.0/Object.html#method-i-clone

You can override them inside of your customized class to produce a deep copy in a different area of memory.

A common idiom in Ruby is to use the Marshal#load and Marshal#dump methods of the Object superclass to produce deep copies. (Note: these methods are normally used to serialize/deserialze objects).

 def dup
   new_grid = Marshal.load( Marshal.dump(@grid) )

   new_grid
 end

irb(main):007:0> x = TestGrid.new([[1,2],[3,4]])
=> 1|2
3|4

irb(main):008:0> y = x.dup
=> [[1, 2], [3, 4]]
irb(main):009:0> x.swap([0,1],[1,1])
=> [4, 2]
irb(main):010:0> puts x
1|4
3|2
=> nil
irb(main):011:0> y
=> [[1, 2], [3, 4]]
irb(main):012:0> puts y
1
2
3
4
=> nil
irb(main):013:0>

y remains the same after the swap.

Alternatively, create a new array, iterate through @grid and push its subarrays into the array.

 def dup
   new_grid = []

   @grid.each do |g|
      new_grid << g
   end

   new_grid
 end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!