我正在构建自己的网络服务器并希望制作记录器。服务器收到消息后,我希望两者都记录它并将消息发送给解析器。我需要对消息进行一些修改以进行记录(例如删除密码),但是当我更改第二个变量时,首先也会更改!
msg = log_msg = JSON.parse(something)
log_msg[:password] = '[FILTERED]'
raise msg.inspect # => {..., :password => '[FILTERED]'}
如何避免代码的这种行为?
更新由于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
答案 0 :(得分:2)
分配后,msg
和log_msg
引用到同一个对象。如果这不是您的预期,请尝试:
log_msg = JSON.parse(something)
msg = log_msg.dup
请注意,另一个示例的行为有所不同,因为Fixnum
很特殊。来自the manual:
Fixnum
个对象具有直接价值。这意味着当它们作为参数分配或传递时,将传递实际对象,而不是对该对象的引用。
答案 1 :(得分:1)
这个问题与以下问题密切相关:
请仔细阅读以了解正在发生的事情(这会解决您的代码段并指定integer
值)。
要按值分配,您可以使用clone
或dup
种方法。检查object_id
的值,以了解您是否正在处理同一个对象。
a = {} # => {}
b = a # => {}
b.object_id # => 114493940
a.object_id # => 114493940
b = a.clone # => {}
b.object_id # => 115158164
a.object_id # => 114493940