Reputation: 31
i'm quite a layman in programming and a noob to ruby but find it useful for my work anyway. Cuirrently I work on a rather large script which brought the following unintended effect:
def my_reduce_method(value_hash,some_keys)
value_hash.delete(some_keys)
end
puts all_values
=> all_values
some_values = all_values # start my block with all values (class: hash)
some_values = my_reduce_method(some_values,keys_to_reduce)
# here only some_values should be effected!
puts all_values
=> some_values
Right in the block there is no damage, but the original all_values is lost! How can I ensure that in a certain code block a certain variable is definitely not changed?
Thank you in advance for any input!!!
Upvotes: 1
Views: 135
Reputation: 323
Object#clone preserves the frozen attribute and singleton methods. If you don't need those, what happens to your example, Object#dup is sufficient.
Upvotes: 0
Reputation: 1208
All object assignments in Ruby are reference assignments.
That means, when you do:
some_values = all_values
You're copying the reference(or address) of the object which all_values
is referencing(or pointing).
The solution for your case is simple:
some_values = all_values.clone
.dup
also works usually (can be different depending on the object).
Another thing to be careful about is, when all_values[:x]
has a string and you do:
some_values = all_values.clone
some_values[:x] += 'abc'
This will not change all_values[:x]
because some_values[:x]
gets (is assigned) a new string object.
But if you do:
some_values = all_values.clone
some_values[:x] << 'abc'
Both all_values[:x]
and some_values[:x]
change, because they both reference the same string object.
This is the effect of the shallow copy @Plasmarob mentioned.
Upvotes: 1