summaryrefslogtreecommitdiff
path: root/ext/psych/lib
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-16 06:39:13 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-16 06:39:13 +0000
commitfe0414b5473b5332706126d2a017a9bf235c8146 (patch)
treef4b06b834757fb6879b6a69c1bb19cd949fe7e93 /ext/psych/lib
parenta5c577757ece55432acbed341d299ac8849d633f (diff)
* ext/psych/lib/psych/visitors/yaml_tree.rb: only dump hash
subclasses. Thanks Joe Eli McIlvain <joe.eli.mac@gmail.com> * test/psych/test_hash.rb: test for change git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49276 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/psych/lib')
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb86
1 files changed, 48 insertions, 38 deletions
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb
index f6427ce807..c1039c6db0 100644
--- a/ext/psych/lib/psych/visitors/yaml_tree.rb
+++ b/ext/psych/lib/psych/visitors/yaml_tree.rb
@@ -325,10 +325,11 @@ module Psych
style = Nodes::Scalar::SINGLE_QUOTED
end
- ivars = find_ivars o
+ is_primitive = o.class == ::String
+ ivars = find_ivars o, is_primitive
if ivars.empty?
- unless o.class == ::String
+ unless is_primitive
tag = "!ruby/string:#{o.class}"
plain = false
quote = false
@@ -367,45 +368,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 +439,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 +458,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 +494,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
@@ -524,7 +534,7 @@ module Psych
end
# FIXME: remove this method once "to_yaml_properties" is removed
- def find_ivars target
+ def find_ivars target, is_primitive=false
begin
loc = target.method(:to_yaml_properties).source_location.first
unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb')
@@ -538,7 +548,7 @@ module Psych
# and it's OK to skip it since it's only to emit a warning.
end
- target.instance_variables
+ is_primitive ? [] : target.instance_variables
end
def register target, yaml_obj