Skip to content
This repository

Anchors for custom classes? #63

Open
twelvechairs opened this Issue May 03, 2012 · 2 comments

1 participant

twelvechairs
twelvechairs

I cannot find a way to ensure that my custom classes will anchor properly (not duplicate when the same object exists in two locations) when converted to yaml through encode_with (or quick_emit, or others). Code below:

class NewClass
  attr_accessor :text
  def encode_with(coder)
        coder.map={"text"=>self.text}
  end
end

o=NewClass.new; o.text="hi"

original = [o,o,o]

yaml = Psych.dump original
puts yaml 

This results in 3 individual versions of the same object (no anchor or referencing). Using Syck it defaults to one. I can't find a way to make this reference/anchor rather than duplicate. If there is any simple way of doing so I can't find it on the internet anywhere....

twelvechairs

As a further issue along the same lines, loading anchored objects does not seem to work properly either. An example is shown in the following code:

class ANewClass
    attr_accessor :info
end

a=%q{- &123 !ruby/object:ANewClass
  info: haha
- *123
- *123}

YAML.add_domain_type( "ruby/object", "ANewClass" ) { |type, val|
   res=ANewClass.new
   res.info=val.info
   res
}

loaded=YAML.load(a)
puts loaded.inspect

The expected result would be an array containing 3 versions of the same object. Instead loaded[0] is unique whilst loaded[1] and loaded[2] are the same.

twelvechairs

Hi. Nobody has responded to this yet, but I still live in hope. Anyway - I understand now the issue with my second post (recreating the object isn't necessary) and can get around this (conceptually odd as it seems), but I'm still curious as to the first. I have got around this with a temporary hook to register for anchors all objects created via encode_with (see code below), but I am curious as to why this isn't done by default? Has it been overlooked or is this a deliberate design decision (different to Syck)? Many thanks in advance for any response.

module Psych
  module Visitors
    class YAMLTree
      alias dump_coder_old dump_coder
      def dump_coder o
        res=dump_coder_old(o)
        register(o,res)
        res
      end
    end
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.