зеркало из 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>
|
Tue Dec 2 06:32:02 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* parse.y (ripper_flush_string_content): preserve the dispatched
|
* parse.y (ripper_flush_string_content): preserve the dispatched
|
||||||
|
|
|
@ -271,6 +271,21 @@ module Psych
|
||||||
end
|
end
|
||||||
map
|
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
|
else
|
||||||
revive_hash(register(o, {}), o)
|
revive_hash(register(o, {}), o)
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,6 +27,8 @@ module Psych
|
||||||
|
|
||||||
def key? target
|
def key? target
|
||||||
@obj_to_node.key? target.object_id
|
@obj_to_node.key? target.object_id
|
||||||
|
rescue NoMethodError
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def id_for target
|
def id_for target
|
||||||
|
@ -411,6 +413,18 @@ module Psych
|
||||||
end
|
end
|
||||||
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
|
private
|
||||||
# FIXME: Remove the index and count checks in Psych 3.0
|
# FIXME: Remove the index and count checks in Psych 3.0
|
||||||
NULL = "\x00"
|
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
|
Загрузка…
Ссылка в новой задаче