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!
You can't.
References in Ruby (and in almost every other programming language) point to a single object in memory.
As long as I mutate
h
I'm still working with same reference:If I want a slightly different version of
h
without changingh
it will be stored as a separate object of course:.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.