1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
tenderlove 2015-01-16 06:39:13 +00:00
parent a5c577757e
commit fe0414b547
3 changed files with 55 additions and 44 deletions

View file

@ -1,3 +1,10 @@
Fri Jan 16 15:37:49 2015 Aaron Patterson <aaron@tenderlovemaking.com>
* 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
Fri Jan 16 15:35:21 2015 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych.rb: bump version

View file

@ -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,12 +458,50 @@ 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
end
@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

View file

@ -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'