I'm to to ruby... Currently, I'm stuck in a situation where I'm changing values I'm not intending to and I don't know how to correct it. I have... A class "Model" and a class "DataObject". The "Data Object" class has a method which takes in a "Model" and returns a new "Model". The problem is, my "generate_new_model" method is altering the input "Model" object. The below show basically what I've done to create the objects. Somehow when I define a new "Model" for output and set it's values to the source model's values, when I change the outputModel values it alters the source model. What am I doing wrong? @myModel = Model.new @myData = DataObject.new newModel = @myData.generate_new_model(@myModel) def generate_new_model(modelSource) outputModel = Model.new outputModel = modelSource outputModel.values = "new values" outputModel end
on 2006-01-30 07:13
on 2006-01-30 07:31
> @myModel = Model.new > @myData = DataObject.new > > newModel = @myData.generate_new_model(@myModel) > > > def generate_new_model(modelSource) > outputModel = Model.new So far, so good. At the minute, outputModel references a brand new Model. > outputModel = modelSource Now, however, it references the same model as modelSource. Oops. > outputModel.values = "new values" And here you've changed the values of the Model referenced by outputModel and modelSource. > outputModel > end Am I right in guessing that you're trying to put a copy of modelSource into outputModel? If so, you might want to take a look at this: http://www.rubygarden.org/ruby?Make_A_Deep_Copy_Of_An_Object Depending on the structure of the Model class, it might be better to give it its own copy method. matthew smillie.
on 2006-01-30 07:43
> > Am I right in guessing that you're trying to put a copy of > modelSource into outputModel? That's exactly the case. In reading the link you suggest it seems I would have to use a seperate data dumping operation. This seems a little strange to me. Shouldn't there be a more simple way to create a copy of an object?
on 2006-01-30 07:50
Just to provide some direct information for anyone who might find this and need the help... The below does indeed solve the problem... class Model def deep_clone Marshal::load(Marshal.dump(self)) end end a = Model.new b = Model.deep_clone Thank you very much for your help.
on 2006-01-30 08:07
On Jan 30, 2006, at 6:43, Todd S. wrote: > In reading the link you suggest it seems I > would have to use a seperate data dumping operation. This seems a > little strange to me. Shouldn't there be a more simple way to > create a > copy of an object? > There is and there isn't: Object#dup and #clone both make shallow copies: http://ruby-doc.org/core/classes/Object.html#M001067 There's no built-in method to create deep copies of any object, though, and the serialise/unserialise thing just hacks around that in the quickest way (as in, quickest to write). If it were me, unless the Model class was extraordinarily complicated, I'd probably just write my own copy method. matthew smillie.
on 2006-01-30 14:52
On Jan 30, 2006, at 1:50 AM, Todd S. wrote: > > a = Model.new > b = Model.deep_clone > > Thank you very much for your help. > > -- > Posted via http://www.ruby-forum.com/. > This isn't perfect but: class Object def deeper_copy copy = self.dup self.instance_variables.each do |ivar| copy.instance_variable_set(ivar, self.instance_variable_get(ivar).dup) end copy end end Note that this is specifically designed to work for regular style classes (ie ones that store everything in instance variables) and for Strings, Arrays and Structs its no better than (but no worse than) #dup. Hence "deeper_copy" instead of "deep_copy"
on 2006-02-01 22:54
Matthew Smillie wrote: > http://ruby-doc.org/core/classes/Object.html#M001067 > > There's no built-in method to create deep copies of any object, > though, and the serialise/unserialise thing just hacks around that in > the quickest way (as in, quickest to write). > > If it were me, unless the Model class was extraordinarily > complicated, I'd probably just write my own copy method. You can as well override or reimplement the #dup method. robert