diff options
Diffstat (limited to 'ext/psych/lib/psych/visitors/yaml_tree.rb')
-rw-r--r-- | ext/psych/lib/psych/visitors/yaml_tree.rb | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 5a092850c3..80af0466eb 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -159,13 +159,13 @@ module Psych end def visit_Regexp o - @emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY + register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY) end def visit_DateTime o formatted = format_time o.to_time tag = '!ruby/object:DateTime' - @emitter.scalar formatted, nil, tag, false, false, Nodes::Scalar::ANY + register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY) end def visit_Time o @@ -174,7 +174,7 @@ module Psych end def visit_Rational o - @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK) + register o, @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK) [ 'denominator', o.denominator.to_s, @@ -187,7 +187,7 @@ module Psych end def visit_Complex o - @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK) + register o, @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK) ['real', o.real.to_s, 'image', o.imag.to_s].each do |m| @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY @@ -214,6 +214,10 @@ module Psych end end + def visit_BigDecimal o + @emitter.scalar o._dump, nil, '!ruby/object:BigDecimal', false, false, Nodes::Scalar::ANY + end + def binary? string string.encoding == Encoding::ASCII_8BIT || string.index("\x00") || @@ -241,9 +245,15 @@ module Psych ivars = find_ivars o if ivars.empty? + unless o.class == ::String + tag = "!ruby/string:#{o.class}" + end @emitter.scalar str, nil, tag, plain, quote, style else - @emitter.start_mapping nil, '!str', false, Nodes::Mapping::BLOCK + maptag = '!ruby/string' + maptag << ":#{o.class}" unless o.class == ::String + + @emitter.start_mapping nil, maptag, false, Nodes::Mapping::BLOCK @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY @emitter.scalar str, nil, tag, plain, quote, style @@ -255,16 +265,16 @@ module Psych def visit_Module o raise TypeError, "can't dump anonymous module: #{o}" unless o.name - @emitter.scalar o.name, nil, '!ruby/module', false, false, Nodes::Scalar::SINGLE_QUOTED + register o, @emitter.scalar(o.name, nil, '!ruby/module', false, false, Nodes::Scalar::SINGLE_QUOTED) end def visit_Class o raise TypeError, "can't dump anonymous class: #{o}" unless o.name - @emitter.scalar o.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED + register o, @emitter.scalar(o.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED) end def visit_Range o - @emitter.start_mapping nil, '!ruby/range', false, Nodes::Mapping::BLOCK + register o, @emitter.start_mapping(nil, '!ruby/range', false, Nodes::Mapping::BLOCK) ['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m| accept m end @@ -297,9 +307,13 @@ module Psych end def visit_Array o - register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) - o.each { |c| accept c } - @emitter.end_sequence + if o.class == ::Array + register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) + o.each { |c| accept c } + @emitter.end_sequence + else + visit_array_subclass o + end end def visit_NilClass o @@ -311,6 +325,39 @@ module Psych end private + def visit_array_subclass o + tag = "!ruby/array:#{o.class}" + if o.instance_variables.empty? + node = @emitter.start_sequence(nil, tag, false, Nodes::Sequence::BLOCK) + register o, node + o.each { |c| accept c } + @emitter.end_sequence + else + node = @emitter.start_mapping(nil, tag, false, Nodes::Sequence::BLOCK) + register o, node + + # Dump the internal list + accept 'internal' + @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) + o.each { |c| accept c } + @emitter.end_sequence + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping(nil, nil, true, Nodes::Sequence::BLOCK) + o.instance_variables.each do |ivar| + accept ivar + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end + + def dump_list o + end + # '%:z' was no defined until 1.9.3 if RUBY_VERSION < '1.9.3' def format_time time |