Forum: Ruby misunderstanding the Passing of references

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Bd3a9ca8a116e0055e65dd2d6069c946?d=identicon&s=25 Todd S. (tdog)
on 2006-01-30 07:13
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
31af45939fec7e3c4ed8a798c0bd9b1a?d=identicon&s=25 Matthew Smillie (Guest)
on 2006-01-30 07:31
(Received via mailing list)
> @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.
Bd3a9ca8a116e0055e65dd2d6069c946?d=identicon&s=25 Todd S. (tdog)
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?
Bd3a9ca8a116e0055e65dd2d6069c946?d=identicon&s=25 Todd S. (tdog)
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.
31af45939fec7e3c4ed8a798c0bd9b1a?d=identicon&s=25 Matthew Smillie (Guest)
on 2006-01-30 08:07
(Received via mailing list)
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.
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-01-30 14:52
(Received via mailing list)
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"
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-02-01 22:54
(Received via mailing list)
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
This topic is locked and can not be replied to.