Reputation: 1990
I have some large hashes (>10⁵ keys) with interlocking structures. They're stored on disk as YAML. I'd like to avoid duplication by using anchors and references in the YAML, but I haven't been able to figure out if there's a way to do it implicitly in the hash such that the #to_yaml
method will label the anchor nodes properly.
Desired YAML:
---
parent1:
common-element-1: &CE1
complex-structure-goes: here
parent2:
uncomment-element-1:
blah: blah
<<: *CE1
Ruby code:
hsh = {
'parent1' => {
'common-element-1' => {
'complex-structure-goes' => 'here',
},
'parent2' => {
'uncommon-element-1' => {
'blah' => 'blah',
},
'<<' => '*CE1',
},
}
The reference is quite straightforward -- but how to embed the &CE1
anchor in the 'common-element-1'
item in the Ruby hash?
I want to work as much as possible with native Ruby primitive types (like Hash
) rather than mucking about with builders and emitters and such -- and I definitely don't want to write the YAML manually!
I've looked at Read and write YAML files without destroying anchors and aliases? and its relative, among other places, but haven't found an answer yet -- at least not that I've understood.
Thanks!
Upvotes: 3
Views: 422
Reputation: 8101
If you use the same Ruby object, the YAML library will set up references for you:
> common = {"ohai" => "I am common"}
> doc = {"parent1" => {"id" => 1, "stuff" => common}, "parent2" => {"id" => 2, "stuff" => common}}
> puts doc.to_yaml
---
parent1:
id: 1
stuff: &70133422893680
ohai: I am common
parent2:
id: 2
stuff: *70133422893680
I'm not sure there's a straightforward way of defining Hashes that are subsets of each other, though. Perhaps tweaking your structure a bit would be warranted?
Upvotes: 4