Object#clone and Object#dup

Hi,

I’d like to duplicate n object, work on the copy, and be sure the original
isn’t change at all. How can I do that?

From the pickaxe (example similar to what I’m working on):

class Klass
attr_accessor :str
end

s1 = Klass.new
=> #Klass:0x4031ad18
s1.str = “Hello”
=> "Hello"
s2 = s1.dup
=> #<Klass:0x4030fcb0 @str=“Hello”>
s2.str[1,4] = “i”
=> “i”

s1.str
=> “Hi”

s2.str
=> “Hi”

I would like that s1.str still returns “Hello”. I tried with dup and clone,
with the same result… What method should I use?

Thanks

Raph

Raphael Bauduin wrote:

Hi,

I’d like to duplicate n object, work on the copy, and be sure the original
isn’t change at all. How can I do that?

Use the deep copy technic:
class Object
def deepcopy
Marshal::load(Marshal::dump(self))
end
end

Lio

Object#dup or Object#clone methods create a shallow copy of the object.
If you need a deep copy you have to do it either like this:

$ irb
irb(main):001:0> class Klass
irb(main):002:1> attr_accessor :str
irb(main):003:1> def initialize_copy(o)
irb(main):004:2> @str = o.str.dup
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> s1 = Klass.new
=> #Klass:0x352bc4
irb(main):008:0> s1.str = “Hello”
=> “Hello”
irb(main):009:0> s2 = s1.dup
=> #<Klass:0x3452d0 @str=“Hello”>
irb(main):010:0> s2.str[1,4] = ‘i’
=> “i”
irb(main):011:0> s1.str
=> “Hello”
irb(main):012:0> s2.str
=> “Hi”
irb(main):013:0>

or like that:

$ irb
irb(main):001:0> class Klass
irb(main):002:1> attr_accessor :str
irb(main):003:1> end
=> nil
irb(main):004:0> s1 = Klass.new
=> #Klass:0x35bcc4
irb(main):005:0> s1.str = “Hello”
=> “Hello”
irb(main):006:0> s2 = Marshal.load(Marshal.dump(s1))
=> #<Klass:0x34ff00 @str=“Hello”>
irb(main):007:0> s2.str[1,4] = ‘i’
=> “i”
irb(main):008:0> s1
=> #<Klass:0x35bcc4 @str=“Hello”>
irb(main):009:0> s1.str
=> “Hello”
irb(main):010:0> s2.str
=> “Hi”
irb(main):011:0>

Cheers,
Kent.

···

On Mar 13, 2004, at 8:49 AM, Raphael Bauduin wrote:

Hi,

I’d like to duplicate n object, work on the copy, and be sure the
original
isn’t change at all. How can I do that?

From the pickaxe (example similar to what I’m working on):

class Klass
attr_accessor :str
end

s1 = Klass.new
=> #Klass:0x4031ad18
s1.str = “Hello”
=> “Hello”
s2 = s1.dup
=> #<Klass:0x4030fcb0 @str=“Hello”>
s2.str[1,4] = “i”
=> “i”

s1.str
=> “Hi”

s2.str
=> “Hi”

I would like that s1.str still returns “Hello”. I tried with dup and
clone,
with the same result… What method should I use?

Thanks

Raph

I’d like to duplicate n object, work on the copy, and be sure the original
isn’t change at all. How can I do that?
[snip]

Define your own #clone method, like this:

ruby a.rb
#<A:0x810a760 @str=“hellochanged!”>
#<A:0x810a74c @str=“hellochanged!”>
ruby a.rb
#<A:0x810a60c @str=“hellochanged!”>
#<A:0x810a5d0 @str=“hello”>
expand -t2 a.rb
class A
def initialize(str)
@str = str
end
attr_reader :str
def change!
@str << “changed!”
end
def clone
A.new(@str.clone)
end
end

a = A.new(“hello”)
b = a.clone
a.change!
p a, b

···

On Sat, 13 Mar 2004 14:44:54 +0100, Raphael Bauduin wrote:


Simon Strandgaard

I use the suggested Marshall way:

Marshal::load(Marshal::dump(self))

and it’s working as I wanted.

Thanks for the help!

Raph

Raphael Bauduin wrote:

···

Hi,

I’d like to duplicate n object, work on the copy, and be sure the original
isn’t change at all. How can I do that?

From the pickaxe (example similar to what I’m working on):

class Klass
attr_accessor :str
end

s1 = Klass.new
=> #Klass:0x4031ad18
s1.str = “Hello”
=> “Hello”
s2 = s1.dup
=> #<Klass:0x4030fcb0 @str=“Hello”>
s2.str[1,4] = “i”
=> “i”

s1.str
=> “Hi”

s2.str
=> “Hi”

I would like that s1.str still returns “Hello”. I tried with dup and clone,
with the same result… What method should I use?

Thanks

Raph