summaryrefslogtreecommitdiff
path: root/ext/psych
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-18 01:44:21 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-18 01:44:21 +0000
commitee3ebc2de5a2d65c718190e8dc230964b683c167 (patch)
treeeb2793016f0a79ba2869be444d3b3d0b9add633b /ext/psych
parente58d77bdda5b905f6694e19bd3e7289597a49c22 (diff)
* ext/psych/lib/psych/visitors/to_ruby.rb: Added ability to load array
subclasses with ivars. * ext/psych/lib/psych/visitors/yaml_tree.rb: Added ability to dump array subclasses with ivars. * test/psych/test_array.rb: corresponding tests git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34328 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/psych')
-rw-r--r--ext/psych/lib/psych/visitors/to_ruby.rb16
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb43
2 files changed, 56 insertions, 3 deletions
diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb
index bf48f9d029..bb29c8b52d 100644
--- a/ext/psych/lib/psych/visitors/to_ruby.rb
+++ b/ext/psych/lib/psych/visitors/to_ruby.rb
@@ -119,6 +119,11 @@ module Psych
map[accept(a.children.first)] = accept a.children.last
}
map
+ when /^!(?:seq|ruby\/array):(.*)$/
+ klass = resolve_class($1)
+ list = register(o, klass.allocate)
+ o.children.each { |c| list.push accept c }
+ list
else
list = register(o, [])
o.children.each { |c| list.push accept c }
@@ -135,6 +140,17 @@ module Psych
members = Hash[*o.children.map { |c| accept c }]
string = members.delete 'str'
init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
+ when /^!ruby\/array:(.*)$/
+ klass = resolve_class($1)
+ list = register(o, klass.allocate)
+
+ members = Hash[o.children.map { |c| accept c }.each_slice(2).to_a]
+ list.replace members['internal']
+
+ members['ivars'].each do |ivar, v|
+ list.instance_variable_set ivar, v
+ end
+ list
when /^!ruby\/struct:?(.*)?$/
klass = resolve_class($1)
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb
index f37396602c..1e22501ad4 100644
--- a/ext/psych/lib/psych/visitors/yaml_tree.rb
+++ b/ext/psych/lib/psych/visitors/yaml_tree.rb
@@ -301,9 +301,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
@@ -315,6 +319,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