I got a little confused about the purpose of objects and pointers in Ruby and encoded this snippet to check my assumptions.
class Foo attr_accessor :one, :two def initialize(one, two) @one = one @two = two end end bar = Foo.new(1, 2) beans = bar puts bar puts beans beans.one = 2 puts bar puts beans puts beans.one puts bar.one
I assumed that when I assigned bar to beans, it will create a copy of the object, and the modification will not affect the other. Alas, the conclusion shows the opposite.
^_^[jergason:~]$ ruby test.rb #<Foo:0x100155c60> #<Foo:0x100155c60> #<Foo:0x100155c60> #<Foo:0x100155c60> 2 2
I believe that the numbers have something to do with the address of the object, and they are the same for beans and for bar, and when I change the beans, the line also changes, which is not something I expected. It looks like I'm only creating a pointer to an object, not a copy of it. What do I need to do to copy an object on assignment instead of creating a pointer?
Tests with the Array class also show strange behavior.
foo = [0, 1, 2, 3, 4, 5] baz = foo puts "foo is #{foo}" puts "baz is #{baz}" foo.pop puts "foo is #{foo}" puts "baz is #{baz}" foo += ["a hill of beans is a wonderful thing"] puts "foo is #{foo}" puts "baz is #{baz}"
This leads to the following result:
foo is 012345 baz is 012345 foo is 01234 baz is 01234 foo is 01234a hill of beans is a wonderful thing baz is 01234
It blows my mind. Calling pop on foo also affects baz, so it is not a copy, but concatenating something on foo only affects foo, not baz. So when do I deal with the original object, and when do I deal with a copy? In my own classes, how can I make sure assignment copies and doesn't make pointers? Help this confused guy.
object variable-assignment ruby copy
jergason
source share