This question has been asked before: Read and write YAML files without destroying anchors and aliases?
I was wondering how to solve that problem with many anchors and aliases?
thanks
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
The problem here is that anchors and aliases in Yaml are a serialization detail, and so aren’t part of the data after it’s been parsed, so the original anchor name isn’t known when writing the data back out to Yaml. In order to keep the anchor names when round tripping you need to store them somewhere when parsing so that they are available later when serializing. In Ruby any object can have instance variables associated with it, so an easy way to achieve this would be to store the anchor name in an instance variable of the objet in question.
Continuing from the example in the earlier question, for hashes we can change our redifined
revive_hashmethod so that if the hash is an anchor then as well as recording the anchor name in the@stvariable so later alises can be recognised, we add the it as an instance variable on the hash.Note that this only affects yaml mappings that are anchors. If you want to have other types to keep their anchor name you’ll need to look at
psych/visitors/to_ruby.rband make sure the name is added in all cases. Most types can be included by overridingregisterbut there are a couple of others; search for@st.Now that the hash has the desired anchor name associated with it, you need to make Psych use it instead of the object id when serializing it. This can be done by subclassing
YAMLTree. WhenYAMLTreeprocesses an object, it first checks to see if that object has been seen already, and emits an alias for it if it has. For any new objects, it records that it has seen the object in case it needs to create an alias later. Theobject_idis used as the key in this, so you need to override those two methods to check for the instance variable, and use that instead if it exists:Now you can use it like this (unlike the previous question, you don’t need to create a custom emitter in this case):