ruby-changes:36594
From: tenderlove <ko1@a...>
Date: Tue, 2 Dec 2014 06:35:26 +0900 (JST)
Subject: [ruby-changes:36594] tenderlove:r48675 (trunk): * ext/psych/lib/psych/visitors/to_ruby.rb: support objects that are
tenderlove 2014-12-02 06:35:11 +0900 (Tue, 02 Dec 2014) New Revision: 48675 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48675 Log: * ext/psych/lib/psych/visitors/to_ruby.rb: support objects that are marshalable, but inherit from basic object. Thanks Sean Griffin <sean@t...> * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto * test/psych/test_marshalable.rb: test for fix Added files: trunk/test/psych/test_marshalable.rb Modified files: trunk/ChangeLog trunk/ext/psych/lib/psych/visitors/to_ruby.rb trunk/ext/psych/lib/psych/visitors/yaml_tree.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 48674) +++ ChangeLog (revision 48675) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Dec 2 06:34:08 2014 Aaron Patterson <aaron@t...> + + * ext/psych/lib/psych/visitors/to_ruby.rb: support objects that are + marshalable, but inherit from basic object. + Thanks Sean Griffin <sean@t...> + + * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto + + * test/psych/test_marshalable.rb: test for fix + Tue Dec 2 06:32:02 2014 Nobuyoshi Nakada <nobu@r...> * parse.y (ripper_flush_string_content): preserve the dispatched Index: ext/psych/lib/psych/visitors/yaml_tree.rb =================================================================== --- ext/psych/lib/psych/visitors/yaml_tree.rb (revision 48674) +++ ext/psych/lib/psych/visitors/yaml_tree.rb (revision 48675) @@ -27,6 +27,8 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/yaml_tree.rb#L27 def key? target @obj_to_node.key? target.object_id + rescue NoMethodError + false end def id_for target @@ -411,6 +413,18 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/yaml_tree.rb#L413 end end + def visit_BasicObject o + tag = Psych.dump_tags[o.class] + tag ||= "!ruby/marshalable:#{o.class.name}" + + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + register(o, map) + + o.marshal_dump.each(&method(:accept)) + + @emitter.end_mapping + end + private # FIXME: Remove the index and count checks in Psych 3.0 NULL = "\x00" Index: ext/psych/lib/psych/visitors/to_ruby.rb =================================================================== --- ext/psych/lib/psych/visitors/to_ruby.rb (revision 48674) +++ ext/psych/lib/psych/visitors/to_ruby.rb (revision 48675) @@ -271,6 +271,21 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/to_ruby.rb#L271 end map + when /^!ruby\/marshalable:(.*)$/ + name = $1 + klass = resolve_class(name) + obj = register(o, klass.allocate) + + if obj.respond_to?(:init_with) + init_with(obj, revive_hash({}, o), o) + elsif obj.respond_to?(:marshal_load) + marshal_data = o.children.map(&method(:accept)) + obj.marshal_load(marshal_data) + obj + else + raise ArgumentError, "Cannot deserialize #{name}" + end + else revive_hash(register(o, {}), o) end Index: test/psych/test_marshalable.rb =================================================================== --- test/psych/test_marshalable.rb (revision 0) +++ test/psych/test_marshalable.rb (revision 48675) @@ -0,0 +1,54 @@ https://github.com/ruby/ruby/blob/trunk/test/psych/test_marshalable.rb#L1 +require_relative 'helper' +require 'delegate' + +module Psych + class TestMarshalable < TestCase + def test_objects_defining_marshal_dump_and_marshal_load_can_be_dumped + sd = SimpleDelegator.new(1) + loaded = Psych.load(Psych.dump(sd)) + + assert_instance_of(SimpleDelegator, loaded) + assert_equal(sd, loaded) + end + + class PsychCustomMarshalable < BasicObject + attr_reader :foo + + def initialize(foo) + @foo = foo + end + + def marshal_dump + [foo] + end + + def mashal_load(data) + @foo = data[0] + end + + def init_with(coder) + @foo = coder['foo'] + end + + def encode_with(coder) + coder['foo'] = 2 + end + + def respond_to?(method) + [:marshal_dump, :marshal_load, :init_with, :encode_with].include?(method) + end + + def class + PsychCustomMarshalable + end + end + + def test_init_with_takes_priority_over_marshal_methods + obj = PsychCustomMarshalable.new(1) + loaded = Psych.load(Psych.dump(obj)) + + assert(PsychCustomMarshalable === loaded) + assert_equal(2, loaded.foo) + end + end +end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/