From 8cd2bf072180a9f733ac06dbaa96f071ca8e8303 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Thu, 9 Jun 2011 01:58:07 +0000 Subject: * 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 --- ext/psych/lib/psych/visitors/to_ruby.rb | 52 ++++++++++++++++++------------- ext/psych/lib/psych/visitors/yaml_tree.rb | 5 ++- 2 files changed, 34 insertions(+), 23 deletions(-) (limited to 'ext/psych') diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb index 3f5be4d4da..2562816344 100644 --- a/ext/psych/lib/psych/visitors/to_ruby.rb +++ b/ext/psych/lib/psych/visitors/to_ruby.rb @@ -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 - 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 + when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/ + revive_hash resolve_class($1).new, o - } - hash + else + 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 }] diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 40198599bf..eef6125ff1 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -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 -- cgit v1.2.3