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>
|
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
|
* 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
|
def visit_Psych_Nodes_Mapping o
|
||||||
return revive(Psych.load_tags[o.tag], o) if Psych.load_tags[o.tag]
|
return revive(Psych.load_tags[o.tag], o) if Psych.load_tags[o.tag]
|
||||||
|
return revive_hash({}, o) unless o.tag
|
||||||
|
|
||||||
case o.tag
|
case o.tag
|
||||||
when '!str', 'tag:yaml.org,2002:str'
|
when '!str', 'tag:yaml.org,2002:str'
|
||||||
|
@ -183,30 +184,12 @@ module Psych
|
||||||
obj = revive((resolve_class(name) || Object), o)
|
obj = revive((resolve_class(name) || Object), o)
|
||||||
@st[o.anchor] = obj if o.anchor
|
@st[o.anchor] = obj if o.anchor
|
||||||
obj
|
obj
|
||||||
|
|
||||||
|
when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/
|
||||||
|
revive_hash resolve_class($1).new, o
|
||||||
|
|
||||||
else
|
else
|
||||||
hash = {}
|
revive_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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -223,6 +206,31 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def revive klass, node
|
||||||
s = klass.allocate
|
s = klass.allocate
|
||||||
h = Hash[*node.children.map { |c| accept c }]
|
h = Hash[*node.children.map { |c| accept c }]
|
||||||
|
|
|
@ -265,7 +265,10 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Hash o
|
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|
|
o.each do |k,v|
|
||||||
accept k
|
accept k
|
||||||
|
|
|
@ -2,11 +2,25 @@ require 'psych/helper'
|
||||||
|
|
||||||
module Psych
|
module Psych
|
||||||
class TestHash < TestCase
|
class TestHash < TestCase
|
||||||
|
class X < Hash
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
super
|
super
|
||||||
@hash = { :a => 'b' }
|
@hash = { :a => 'b' }
|
||||||
end
|
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
|
def test_self_referential
|
||||||
@hash['self'] = @hash
|
@hash['self'] = @hash
|
||||||
assert_cycle(@hash)
|
assert_cycle(@hash)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue