psych icon indicating copy to clipboard operation
psych copied to clipboard

Anchors for custom classes?

Open twelvechairs opened this issue 13 years ago • 2 comments

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 avatar May 03 '12 07:05 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 avatar May 07 '12 08:05 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

twelvechairs avatar Jul 04 '12 02:07 twelvechairs