doIt[‘params’] = ids[rand(6)]
p “Pushing step: #{doIt.inspect}”
setup << doIt
end
p “Final steps list: #{setup.inspect}”
When I inspect my final steps list at the end, the values of
‘doIt[‘params’]’ is always the same - set to the last value of the last
run of the upto loop. But when I inspect doIt prior to pushing it, I
can see that it has its own value, acquired randomly.
So my question is, why is the hash not being pushed onto the array
properly? What side effect am I encountering here and how do I get
around it?
(I’ve already tried declaring “params” => “” in the initial hash
creation; that didn’t help).
Thanks,
Alex
PS - You’d be correct in noting this code doesn’t do anything useful.
I’ve stripped away other parts to isolate the questionable behavior for
demonstration purposes.
so here, doIt is referencing an object which is a hash
cnt = rand(10)
1.upto(cnt) do
doIt[‘params’] = ids[rand(6)]
p “Pushing step: #{doIt.inspect}”
setup << doIt
this puts that reference into the setup array
NOTE: it is always referring to the same hash
can see that it has its own value, acquired randomly.
PS - You’d be correct in noting this code doesn’t do anything useful.
I’ve stripped away other parts to isolate the questionable behavior
for
demonstration purposes.
Try creating the hash object inside the loop (i.e., creating a new
object each time)
Note that I’m also calling .dup on the element taken from the ids
array so there’s a separate string object. You can apply this to your
real code, I hope.
Thanks, Rob. Made the mistake of assuming I get a copy of the hash when
I push it. IIRC, there are other (not-so-elegant) languages that do so.
Appreciate the point about .dup as well, but since at the end of this,
I’m just writing everything out to a file, and the elements of ids will
never change (at least not in this script), I don’t think I need a
duplicate string.
“result” => “true”
p “Final steps list: #{setup.inspect}”
around it?
You are modifying the same hash, then adding the same hash to the array
again. In other words, there is only ever one hash in your program (and
data
is mutable in Ruby).
To analogize, if you record my address ten times, painting my shutters a
different after each, then decide to visit each of the ten addresses
that
you have written down, you will find that all of the houses you visit
will
have the same colour of shutters as the final time you painted my house.
Thanks, Rob. Made the mistake of assuming I get a copy of the hash when
I push it. IIRC, there are other (not-so-elegant) languages that do so.
Appreciate the point about .dup as well, but since at the end of this,
I’m just writing everything out to a file, and the elements of ids will
never change (at least not in this script), I don’t think I need a
duplicate string.
To complement the excellent explanations you have been given already:
the technical term for the effect is “aliasing”.
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.