summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Eli McIlvain <joe.eli.mac@gmail.com>2015-01-15 18:04:45 -0800
committerJoe Eli McIlvain <joe.eli.mac@gmail.com>2015-01-15 18:08:25 -0800
commita1656129c40a6c27a387a0eb45541a0a3a4dd948 (patch)
treef752ed83a31291d329353fec7361648b1eb8edd9
parent47adf879591570daebde62895b3712c216710661 (diff)
downloadpsych-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.rb77
-rw-r--r--test/psych/test_hash.rb6
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'