зеркало из https://github.com/github/ruby.git
* ext/psych/lib/psych/visitors/to_ruby.rb: support objects that are
marshalable, but inherit from basic object. Thanks Sean Griffin <sean@thoughtbot.com> * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto * test/psych/test_marshalable.rb: test for fix git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48675 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
0a190272cd
Коммит
12396fda40
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Tue Dec 2 06:34:08 2014 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||
|
||||
* ext/psych/lib/psych/visitors/to_ruby.rb: support objects that are
|
||||
marshalable, but inherit from basic object.
|
||||
Thanks Sean Griffin <sean@thoughtbot.com>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* parse.y (ripper_flush_string_content): preserve the dispatched
|
||||
|
|
|
@ -271,6 +271,21 @@ module Psych
|
|||
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
|
||||
|
|
|
@ -27,6 +27,8 @@ module Psych
|
|||
|
||||
def key? target
|
||||
@obj_to_node.key? target.object_id
|
||||
rescue NoMethodError
|
||||
false
|
||||
end
|
||||
|
||||
def id_for target
|
||||
|
@ -411,6 +413,18 @@ module Psych
|
|||
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"
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
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
|
Загрузка…
Ссылка в новой задаче