mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/psych/lib/psych/visitors/to_ruby.rb: Hash subclasses can be read
from YAML files. * ext/psych/lib/psych/visitors/yaml_tree.rb: Hash subclasses can be dumped to YAML files. * test/psych/test_hash.rb: corresponding test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
aaa52bf088
commit
8cd2bf0721
4 changed files with 57 additions and 24 deletions
|
@ -1,3 +1,11 @@
|
|||
Thu Jun 9 10:57:03 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||
|
||||
* ext/psych/lib/psych/visitors/to_ruby.rb: Hash subclasses can be read
|
||||
from YAML files.
|
||||
* ext/psych/lib/psych/visitors/yaml_tree.rb: Hash subclasses can be
|
||||
dumped to YAML files.
|
||||
* test/psych/test_hash.rb: corresponding test.
|
||||
|
||||
Thu Jun 9 09:18:51 2011 Aaron Patterson <aaron@tenderlovemaking.com>
|
||||
|
||||
* ext/psych/lib/psych/visitors/to_ruby.rb: Ruby modules can be loaded
|
||||
|
|
|
@ -120,6 +120,7 @@ module Psych
|
|||
|
||||
def visit_Psych_Nodes_Mapping o
|
||||
return revive(Psych.load_tags[o.tag], o) if Psych.load_tags[o.tag]
|
||||
return revive_hash({}, o) unless o.tag
|
||||
|
||||
case o.tag
|
||||
when '!str', 'tag:yaml.org,2002:str'
|
||||
|
@ -183,30 +184,12 @@ module Psych
|
|||
obj = revive((resolve_class(name) || Object), o)
|
||||
@st[o.anchor] = obj if o.anchor
|
||||
obj
|
||||
|
||||
when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/
|
||||
revive_hash resolve_class($1).new, o
|
||||
|
||||
else
|
||||
hash = {}
|
||||
@st[o.anchor] = hash if o.anchor
|
||||
|
||||
o.children.each_slice(2) { |k,v|
|
||||
key = accept(k)
|
||||
|
||||
if key == '<<'
|
||||
case v
|
||||
when Nodes::Alias
|
||||
hash.merge! accept(v)
|
||||
when Nodes::Sequence
|
||||
accept(v).reverse_each do |value|
|
||||
hash.merge! value
|
||||
end
|
||||
else
|
||||
hash[key] = accept(v)
|
||||
end
|
||||
else
|
||||
hash[key] = accept(v)
|
||||
end
|
||||
|
||||
}
|
||||
hash
|
||||
revive_hash({}, o)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -223,6 +206,31 @@ module Psych
|
|||
end
|
||||
|
||||
private
|
||||
def revive_hash hash, o
|
||||
@st[o.anchor] = hash if o.anchor
|
||||
|
||||
o.children.each_slice(2) { |k,v|
|
||||
key = accept(k)
|
||||
|
||||
if key == '<<'
|
||||
case v
|
||||
when Nodes::Alias
|
||||
hash.merge! accept(v)
|
||||
when Nodes::Sequence
|
||||
accept(v).reverse_each do |value|
|
||||
hash.merge! value
|
||||
end
|
||||
else
|
||||
hash[key] = accept(v)
|
||||
end
|
||||
else
|
||||
hash[key] = accept(v)
|
||||
end
|
||||
|
||||
}
|
||||
hash
|
||||
end
|
||||
|
||||
def revive klass, node
|
||||
s = klass.allocate
|
||||
h = Hash[*node.children.map { |c| accept c }]
|
||||
|
|
|
@ -265,7 +265,10 @@ module Psych
|
|||
end
|
||||
|
||||
def visit_Hash o
|
||||
register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK))
|
||||
tag = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}"
|
||||
implicit = !tag
|
||||
|
||||
register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK))
|
||||
|
||||
o.each do |k,v|
|
||||
accept k
|
||||
|
|
|
@ -2,11 +2,25 @@ require 'psych/helper'
|
|||
|
||||
module Psych
|
||||
class TestHash < TestCase
|
||||
class X < Hash
|
||||
end
|
||||
|
||||
def setup
|
||||
super
|
||||
@hash = { :a => 'b' }
|
||||
end
|
||||
|
||||
def test_empty_subclass
|
||||
assert_match "!ruby/hash:#{X}", Psych.dump(X.new)
|
||||
x = Psych.load Psych.dump X.new
|
||||
assert_equal X, x.class
|
||||
end
|
||||
|
||||
def test_map
|
||||
x = Psych.load "--- !map:#{X} { }\n"
|
||||
assert_equal X, x.class
|
||||
end
|
||||
|
||||
def test_self_referential
|
||||
@hash['self'] = @hash
|
||||
assert_cycle(@hash)
|
||||
|
|
Loading…
Reference in a new issue