Ruby Hash Key Reference

青春壹個敷衍的年華 提交于 2019-12-25 00:52:42

问题


Hello I have a custom Hash that needs to be returned in an API. But currently I'm struggling to find a good way to do so. The following example will describe the problem.

Lets say we have the following code:

data = {name: "Jon", value: "13"}
results = []

[1, 2, 3, 4, 5].each do |i|
  data[:id] = i
  results << data
end

# output 
# results = [{name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}]

I expected something like this:

# results = [{name: "Jon", value: "13", id: 1}, {name: "Jon", value: "13", id: 2}, {name: "Jon", value: "13", id: 3}, {name: "Jon", value: "13", id: 4}, {name: "Jon", value: "13", id: 5}]

How can I achieve this format efficiently (memory usage)? The following code fixes the reference issue (because it creates a new hash) but is inefficient, because my initial hash 'data' is really big.

# inefficient but working
[1, 2, 3, 4, 5].each do |i|
  data[:id] = i
  results << data.dup
end

# output
# results = [{name: "Jon", value: "13", id: 1}, {name: "Jon", value: "13", id: 2}, {name: "Jon", value: "13", id: 3}, {name: "Jon", value: "13", id: 4}, {name: "Jon", value: "13", id: 5}]

Thank you!


回答1:


You can't.

References in Ruby (and in almost every other programming language) point to a single object in memory.

irb(main):004:0> h = { foo: :bar }
=> {:foo=>:bar}
irb(main):005:0> h.object_id
=> 70125571572420

As long as I mutate h I'm still working with same reference:

irb(main):006:0> h[:bar] = 'baz'
=> "baz"
irb(main):007:0> h.object_id
=> 70125571572420

If I want a slightly different version of h without changing h it will be stored as a separate object of course:

h.merge(x: 2).object_id
=> 70125567041320

.merge in this case duplicates the hash and returns the result of merging it with args.

There is no way around this. Hashes in Ruby cannot "inherit" from a reference.



来源:https://stackoverflow.com/questions/46330186/ruby-hash-key-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!