Reputation: 15146
I'm in the process of building my own webserver and want to make a logger. After server get a message, I want both to log it and send the message to the parsers. I need to make some moditications to the message for logging (eg remove the password), but when I change second variable, first is changed too!
msg = log_msg = JSON.parse(something)
log_msg[:password] = '[FILTERED]'
raise msg.inspect # => {..., :password => '[FILTERED]'}
How can I avoid this behavior of my code?
UPDATED It seems more strange, because of irb
:
2.2.1 :001 > a = b = 1
=> 1
2.2.1 :002 > b = 2
=> 2
2.2.1 :003 > b
=> 2
2.2.1 :004 > a
=> 1
Upvotes: 0
Views: 960
Reputation: 122383
After the assignment, msg
and log_msg
reference to the same object. If this is not what you expected, try this:
log_msg = JSON.parse(something)
msg = log_msg.dup
Note that the other example behave differently because Fixnum
is special. From the manual:
Fixnum
objects have immediate value. This means that when they are assigned or passed as parameters, the actual object is passed, rather than a reference to that object.
Upvotes: 2
Reputation: 3438
This question is tightly linked to the following duscussions:
Please read them carefully to understand what's going on (this addressed your code snippet with assigning integer
values aswell).
To assign by value you could clone
or dup
methods. Check the value of object_id
to realize if you're working on the same object or not.
a = {} # => {}
b = a # => {}
b.object_id # => 114493940
a.object_id # => 114493940
b = a.clone # => {}
b.object_id # => 115158164
a.object_id # => 114493940
Upvotes: 1