Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > cloning object with array members

Reply
Thread Tools

cloning object with array members

 
 
Shea Martin
Guest
Posts: n/a
 
      01-05-2007
Consider a simple class like this:
class MyClass
def initialize
@var1 = ''
@arr1 = []
end
end


Now if I have an instance of MyClass, and want to clone it, what is the
'cleanest' way to do this?

a = MyClass.new
b = a.clone

This method leaves 'b.arr1' pointing to the same data as a.arr1.

Hmmm... I'll try overriding clone, and manually deal with the arrays:

def clone
rslt = super.clone
end

This blows the stack, I believe because all methods are inherited virtually.

Ok, so now I have to manually copy everything in clone, whatever, I am
getting sick of this:

def clone
rslt = MyClass.new
rslt.var1 = @var1
rslt.arr1 = @arr1.clone
rslt
end

Turns out this does not compute either, as there is no method var1= or
arr1= ! I want to keep var1 private, so can't go this route either.


One more attempt:
def clone
rslt = MyClass.new

self.instance_variables.each do |member|
rslt.instance_variable_set( member,
self.instance_variable_get(member).clone )
end
end

This fails as the methos do not seem to copy over.

There has to be a simple way to do something like this? What is common
recipe for something like this? Should this really be that hard in ruby?

~S
 
Reply With Quote
 
 
 
 
dblack@wobblini.net
Guest
Posts: n/a
 
      01-05-2007
Hi --

On Sat, 6 Jan 2007, Shea Martin wrote:

> Consider a simple class like this:
> class MyClass
> def initialize
> @var1 = ''
> @arr1 = []
> end
> end
>
>
> Now if I have an instance of MyClass, and want to clone it, what is the
> 'cleanest' way to do this?
>
> a = MyClass.new
> b = a.clone
>
> This method leaves 'b.arr1' pointing to the same data as a.arr1.


I don't see an a.arr1 method. Did you mean to create some accessors
methods?

The most common idiom I've seen for deep copying is:

b = Marshal.load(Marshal.dump(a))


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

 
Reply With Quote
 
 
 
 
gwtmp01@mac.com
Guest
Posts: n/a
 
      01-05-2007

On Jan 5, 2007, at 4:40 PM, Shea Martin wrote:
> Hmmm... I'll try overriding clone, and manually deal with the arrays:
>
> There has to be a simple way to do something like this? What is
> common recipe for something like this? Should this really be that
> hard in ruby?


Warning: I didn't test these...

def clone
rslt = super # Use the default #clone instead of Myclass.new

instance_variables.each do |member|
rslt.instance_variable_set( member, instance_variable_get
(member).clone )
end

rslt
end

For your particular case you could avoid the loop of course:

def clone
rslt = super
rslt.instance_variable_set "@var1", @var1.clone
rslt.instance_variable_set "@arr1", @arr1.clone
rslt
end



Gary Wright




 
Reply With Quote
 
Olivier
Guest
Posts: n/a
 
      01-05-2007
> Hmmm... I'll try overriding clone, and manually deal with the arrays:
>
> def clone
> rslt = super.clone
> end
>
> This blows the stack, I believe because all methods are inherited
> virtually.


The method which must be overriden is initialize_copy

def initialize_copy(from)
@arr1 = from.instance_eval('@arr1').clone
end

--
Olivier Renaud

 
Reply With Quote
 
Shea Martin
Guest
Posts: n/a
 
      01-06-2007
Shea Martin wrote:
> Consider a simple class like this:
> class MyClass
> def initialize
> @var1 = ''
> @arr1 = []
> end
> end
>
>
> Now if I have an instance of MyClass, and want to clone it, what is the
> 'cleanest' way to do this?
>
> a = MyClass.new
> b = a.clone
>
> This method leaves 'b.arr1' pointing to the same data as a.arr1.
>
> Hmmm... I'll try overriding clone, and manually deal with the arrays:
>
> def clone
> rslt = super.clone
> end
>
> This blows the stack, I believe because all methods are inherited
> virtually.
>
> Ok, so now I have to manually copy everything in clone, whatever, I am
> getting sick of this:
>
> def clone
> rslt = MyClass.new
> rslt.var1 = @var1
> rslt.arr1 = @arr1.clone
> rslt
> end
>
> Turns out this does not compute either, as there is no method var1= or
> arr1= ! I want to keep var1 private, so can't go this route either.
>
>
> One more attempt:
> def clone
> rslt = MyClass.new
>
> self.instance_variables.each do |member|
> rslt.instance_variable_set( member,
> self.instance_variable_get(member).clone )
> end
> end
>
> This fails as the methos do not seem to copy over.
>
> There has to be a simple way to do something like this? What is common
> recipe for something like this? Should this really be that hard in ruby?
>
> ~S



Thanks for all the help. My last attempt at clone turns out to be fine,
I just forgot to return 'rslt'. That fixed everything.

~S
 
Reply With Quote
 
Pit Capitain
Guest
Posts: n/a
 
      01-06-2007
Shea, you found your answer in the meantime, but I wanted to show you
what was wrong with your other attempts:

>> a = MyClass.new
>> b = a.clone
>>
>> This method leaves 'b.arr1' pointing to the same data as a.arr1.


Yes, the default #dup and #clone create a shallow copy.

>> def clone
>> rslt = super.clone
>> end
>>
>> This blows the stack, I believe because all methods are inherited
>> virtually.


"super" isn't the same as in Java. super calls the same method of the
superclass, so what you are doing here is:

temp = super
rslt = temp.clone

Since temp is an instance of MyClass, you're calling clone again, which
gives you and endless recursion. The correct way would have been:

def clone
super
end

But this obviously doen't help you.

>> def clone
>> rslt = MyClass.new
>> rslt.var1 = @var1
>> rslt.arr1 = @arr1.clone
>> rslt
>> end
>>
>> Turns out this does not compute either, as there is no method var1= or
>> arr1= ! I want to keep var1 private, so can't go this route either.


The solution to this problem was:

>> def clone
>> rslt = MyClass.new
>>
>> self.instance_variables.each do |member|
>> rslt.instance_variable_set( member,
>> self.instance_variable_get(member).clone )
>> end
>> end
>>
>> This fails as the methos do not seem to copy over.


And here, as you've noted yourself, you just forgot to return your new
instance.

Regards,
Pit

 
Reply With Quote
 
Shea Martin
Guest
Posts: n/a
 
      01-09-2007
def clone
rslt = BuildConfig.new

self.instance_variables.each do |member|
rslt.instance_variable_set( member,
self.instance_variable_get(member).clone )
end

return rslt
end

This clone method bombs if any of the instance variables are FixNums,
Floats, boolean, etc. Is there a way in my loop to know if an instance
variable supports 'clone'?

~S
 
Reply With Quote
 
Stefano Crocco
Guest
Posts: n/a
 
      01-09-2007
Alle 22:35, marted=EC 9 gennaio 2007, Shea Martin ha scritto:
> def clone
> rslt =3D BuildConfig.new
>
> self.instance_variables.each do |member|
> rslt.instance_variable_set( member,
> self.instance_variable_get(member).clone )
> end
>
> return rslt
> end
>
> This clone method bombs if any of the instance variables are FixNums,
> Floats, boolean, etc. Is there a way in my loop to know if an instance
> variable supports 'clone'?
>
> ~S


I don't know whether there is a way to know in advance if a variable suppor=
ts=20
clone, so I'd say: try it. If it works, good. If it doesn't, it'll raise an=
=20
exception, which you can rescue:

def clone
rslt =3D BuildConfig.new

self.instance_variables.each do |member|
begin rslt.instance_variable_set( member, self.instance_variable_get(me=
mber).clone )
rescue Exception: rslt.instance_variable_set(member, self.instance_vari=
able_get(member))
end
end

return rslt
end

I'm not an expert, so there may be better ways to do this I don't know, but=
this should work.

Stefano

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Cloning members of a hierarchy Paul N C++ 5 02-01-2010 10:46 PM
class members vs instance members hdixon Python 3 07-09-2006 06:56 PM
Difference between static final members and final static members(if any)? JFCM Java 4 02-07-2006 11:32 AM
Templates: Members Vs. non-members Dave C++ 3 08-10-2004 11:23 AM
Can nested class members access private members of nesting class? CoolPint C++ 8 12-14-2003 02:30 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57