Losing sanity, please help!

OK, I'm still trying to move a pic between albums, but this time I'm going totally ballistic. Please see the debugger session below. The model is simple, class Pic acts_as_list and belongs_to :album.

Can someone please please please explain to me why @old_alb changes its value after line 73 ?

######### debugger session:

[64, 73] in ./script/../config/../app/controllers/pic_controller.rb    64 redirect_to :action=>:list and return    65 end    66 Debugger.start    67 debugger    68 => 69 @old_alb=@pic.album    70 if @pic.update_attributes(params[:pic])    71 @pic.set_tags @params[:tags]    72 @pic.album =Album.find(params[:album][:id])    73 @pic.save (rdb:90) n ./script/../config/../app/controllers/pic_controller.rb:70 if @pic.update_attributes(params[:pic]) (rdb:90) p @old_alb.id 2 (rdb:90) n ./script/../config/../app/controllers/pic_controller.rb:71 @pic.set_tags @params[:tags] (rdb:90) n ./script/../config/../app/controllers/pic_controller.rb:72 @pic.album =Album.find(params[:album][:id]) (rdb:90) n ./script/../config/../app/controllers/pic_controller.rb:73 @pic.save (rdb:90) n ./script/../config/../app/controllers/pic_controller.rb:74 if @old_alb != @pic.album (rdb:90) p @old_alb.id 1 ######### end debugging session

TIA, sleepless somewhere.

Variables in Ruby are just references to an Object. So if you do a = b and change b, you change the object b refers to. As a refers tothe same object, the value of a will change too.

Solution *should* be (just looked this up, didn't try and never had this problem myself before):

a = b.dup

Thanks for your suggestion, but it doesn't seem true to me, in a simple case below all works as expected:

foo=Album.find 1

=> #<Album:0xb7186638 @attributes={"created_on"=>"2007-04-25 03:28:30", "name"=>"top album", "text"=>nil, "id"=>"1", "user_id"=>"1", "parent_id"=>nil}>

bar=foo

=> #<Album:0xb7186638 @attributes={"created_on"=>"2007-04-25 03:28:30", "name"=>"top album", "text"=>nil, "id"=>"1", "user_id"=>"1", "parent_id"=>nil}>

foo=Album.find 2

=> #<Album:0xb717b92c @attributes={"created_on"=>"2007-04-25 03:45:25", "name"=>"п©я─п╬п╡п╣я─п╨п╟", "text"=>"п╡п╬я┌ я┌п╟п╨", "id"=>"2", "user_id"=>"1", "parent_id"=>"1"}>

bar==foo

=> false

So why might it work otherwise in my app?

rgds, Dmitry

Your example is different from your real problem:

your problem:

1) A = Something 2) B = A 3) You CHANGE the OBJECT that A refers to. A -----           \ _ Object (If you change B.album, the Object here is changed, and as A points to the same Object in memory, it has "changed" to           / B -----

4) As B points to the same object, B has "changed" too (or the object it refers to, accuratly spoken)

In your example that you just posted, however, you do something different:

1) foo = Something 2)bar = foo 3) You set A to point to a NEW, DIFFERENT OBJECT (namely the one created by "Album.find 2" ) foo -------              \ _ Object (now you don't change the Object, but you create a new one, and make foo point to it)              / bar -------

result:

foo -------> new Object

bar -------> old Object

4) bar points to the object created in 1) , foo points to the Object created in 3)

See the difference in 3) ? in your real problem, you change the OBJECT that both variables point to. in your second example, you make "foo" POINT to a different, freshly created Object.

just give the .dup method a try. and don't be bothered by my usage of Caps, i just tried to emphasise the crucial differences :wink:

Thorsten, you're DA MAN! My sanity is restored, thanks!