diff options
author | Joe Eli McIlvain <joe.eli.mac@gmail.com> | 2015-01-15 18:04:45 -0800 |
---|---|---|
committer | Joe Eli McIlvain <joe.eli.mac@gmail.com> | 2015-01-15 18:08:25 -0800 |
commit | a1656129c40a6c27a387a0eb45541a0a3a4dd948 (patch) | |
tree | f752ed83a31291d329353fec7361648b1eb8edd9 | |
parent | 47adf879591570daebde62895b3712c216710661 (diff) | |
download | psych-a1656129c40a6c27a387a0eb45541a0a3a4dd948.tar.gz |
Only dump ivars for subclasses of Hash, not for Hash.
Fixes #216.
Fixes part of #217.
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 77 | ||||
-rw-r--r-- | test/psych/test_hash.rb | 6 |
2 files changed, 43 insertions, 40 deletions
diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index f6427ce..35ebb27 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -367,45 +367,15 @@ module Psych end def visit_Hash o - ivars = o.instance_variables - - if ivars.any? - tag = "!ruby/hash-with-ivars" - tag << ":#{o.class}" unless o.class == ::Hash - - register(o, @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)) - - @emitter.scalar 'elements', nil, nil, true, false, Nodes::Scalar::ANY - - @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + if o.class == ::Hash + register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| accept k accept v end @emitter.end_mapping - - @emitter.scalar 'ivars', nil, nil, true, false, Nodes::Scalar::ANY - - @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK - o.instance_variables.each do |ivar| - accept ivar - accept o.instance_variable_get ivar - end - @emitter.end_mapping - - @emitter.end_mapping else - 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 - accept v - end - - @emitter.end_mapping + visit_hash_subclass o end end @@ -468,7 +438,8 @@ module Psych def visit_array_subclass o tag = "!ruby/array:#{o.class}" - if o.instance_variables.empty? + ivars = o.instance_variables + if ivars.empty? node = @emitter.start_sequence(nil, tag, false, Nodes::Sequence::BLOCK) register o, node o.each { |c| accept c } @@ -486,6 +457,35 @@ module Psych # Dump the ivars accept 'ivars' @emitter.start_mapping(nil, nil, true, Nodes::Sequence::BLOCK) + ivars.each do |ivar| + accept ivar + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end + + def visit_hash_subclass o + ivars = o.instance_variables + if ivars.any? + tag = "!ruby/hash-with-ivars:#{o.class}" + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + + # Dump the elements + accept 'elements' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.each do |k,v| + accept k + accept v + end + @emitter.end_mapping + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK o.instance_variables.each do |ivar| accept ivar accept o.instance_variable_get ivar @@ -493,6 +493,15 @@ module Psych @emitter.end_mapping @emitter.end_mapping + else + tag = "!ruby/hash:#{o.class}" + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + o.each do |k,v| + accept k + accept v + end + @emitter.end_mapping end end diff --git a/test/psych/test_hash.rb b/test/psych/test_hash.rb index 066df66..e658984 100644 --- a/test/psych/test_hash.rb +++ b/test/psych/test_hash.rb @@ -38,12 +38,6 @@ module Psych assert_cycle t1 end - def test_hash_with_ivars - @hash.instance_variable_set :@foo, 'bar' - dup = Psych.load Psych.dump @hash - assert_equal 'bar', dup.instance_variable_get(:@foo) - end - def test_hash_subclass_with_ivars x = X.new x[:a] = 'b' |