Rubysters,
I had the following code working nicely:
(a) http://pastie.org/private/8qn4f36mfeppbobm7b2wsa
At the beginning of every iteration, I expect "essential_params" hash (in
line 8) to look like this: essential_params  = {:val_1 => 0, :val_2 =>
[x,y,z], :val_3 =>0}. However it does repetitive work to initialize a hash
from a database (in line 8).
So as to reduce repetitive database querying (at every iteration), I have
just moved hash initialization to (line 7) outside a loop:
(b) http://pastie.org/private/iudfe0q2s41vszxby6vva
Now the code acts wierd: At every iteration,  my "essential_params" hash
contains data accumulated from the previous iterations. For example, at the
nth iteration, essential_params may look like this: {:val_1 => 25, :val_2 =>
[x,y,z], :val_3 =>24} which are results from (n-1)th iteration (instead of
the default values: {:val_1 => 0, :val_2 => [x,y,z], :val_3 =>0}).
Well, first of all, it seems that essential_params has a key
:params_hash, so I guess it's something like:
essential_params = {:params_hash => {:val_1 => 0, :val_2 => [x,y,z],
:val_3 =>0}}
If this is the case, then you are overwriting the values of the
params_hash in lines 22 and 23. When you do this:
new_data[:params_hash]  = essential_params[:params_hash]
you are referencing one hash (essential_params[:params_hash]) from the
other hash. So when, after that, you do this:
new_data[:params_hash][:val_1] = 25
you are changing the original hash object.
Does anyone have a better explanation about this? Are Ruby hashed assigned
by value or by reference? (Specifically, why is the pre-populated hash at
line 7 in (b) getting values from lines 22 and 23 ? )
Everything in Ruby is an object. When you assign to a variable, you
are making the variable reference the object. When you call a method
through the variable, you are sending that message to the object. An
object can be referenced by several variables. Check this:
ruby-1.8.7-p334 :001 > a = {}
=> {}
ruby-1.8.7-p334 :002 > a.object_id
=> -611696338
ruby-1.8.7-p334 :003 > b = a
=> {}
ruby-1.8.7-p334 :004 > b.object_id
=> -611696338
Both a and b are variables that point to the same object. There's only
one hash. So when you change the hash, be it through a or through b
you are changing the same object:
ruby-1.8.7-p334 :005 > b[:val] = 3
=> 3
ruby-1.8.7-p334 :006 > a
=> {:val=>3}
This is basically what you are seeing in your code (a is
essential_params[:params_hash] and b is new_data[:params_hash]).
You might want to create a copy of the hash so that the original hash
is not modified. You can do that with Object#dup.
ruby-1.8.7-p334 :007 > a = {:val => 3}
=> {:val=>3}
ruby-1.8.7-p334 :008 > b = a.dup
=> {:val=>3}
ruby-1.8.7-p334 :009 > b[:val] = 5
=> 5
ruby-1.8.7-p334 :010 > a
=> {:val=>3}
ruby-1.8.7-p334 :011 > b
=> {:val=>5}
So, modify your line 15 to this:
      new_data[:params_hash]  = essential_params[:params_hash].dup
and let us know if it worked for you.
Hope this helps,
Jesus.
···
On Tue, Oct 25, 2011 at 3:50 PM, Edmond Kachale <kachaleedmond@gmail.com> wrote: