summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2009-10-08 21:39:09 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2009-10-08 21:39:09 -0700
commitc7893568eab3e1eeab3febaa011dc43cea505abe (patch)
tree9524354b896a7ffe88a2339e82d5b532359cb0db
parentcaa82b9e8139c36d8aeaa68e9465eaeef7ec7675 (diff)
downloadpsych-c7893568eab3e1eeab3febaa011dc43cea505abe.zip
object subclass working
-rw-r--r--lib/psych/visitors/to_ruby.rb11
-rw-r--r--lib/psych/visitors/yast_builder.rb10
-rw-r--r--test/psych/test_serialize_subclasses.rb23
3 files changed, 44 insertions, 0 deletions
diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb
index f6a4d69..39c9194 100644
--- a/lib/psych/visitors/to_ruby.rb
+++ b/lib/psych/visitors/to_ruby.rb
@@ -97,6 +97,17 @@ module Psych
def visit_Psych_Nodes_Mapping o
case o.tag
+ when /!ruby\/object(:.*)?$/
+ name = $1.sub(/^:/, '')
+ h = Hash[*o.children.map { |c| accept c }]
+ s = name.split('::').inject(Object) { |k,sub|
+ k.const_get sub
+ }.allocate
+ h.each do |k,v|
+ s.instance_variable_set(:"@#{k}", v)
+ end
+ s
+
when /!ruby\/struct(:.*)?$/
klassname = $1
h = Hash[*o.children.map { |c| accept c }].to_a
diff --git a/lib/psych/visitors/yast_builder.rb b/lib/psych/visitors/yast_builder.rb
index 296cb36..11e3b34 100644
--- a/lib/psych/visitors/yast_builder.rb
+++ b/lib/psych/visitors/yast_builder.rb
@@ -22,6 +22,16 @@ module Psych
raise TypeError, "Can't dump #{target.class}"
end
+ def visit_Object o
+ tag = ['!ruby/object', o.class.name].join(':')
+ @stack.push append Nodes::Mapping.new(nil, tag, false)
+ o.instance_variables.each do |iv|
+ accept iv.to_s.sub(/^@/, '')
+ accept o.instance_variable_get(iv)
+ end
+ @stack.pop
+ end
+
def visit_Struct o
tag = ['!ruby/struct', o.class.name].compact.join(':')
diff --git a/test/psych/test_serialize_subclasses.rb b/test/psych/test_serialize_subclasses.rb
new file mode 100644
index 0000000..f500fb1
--- /dev/null
+++ b/test/psych/test_serialize_subclasses.rb
@@ -0,0 +1,23 @@
+require 'minitest/autorun'
+require 'psych'
+
+module Psych
+ class TestSerializeSubclasses < MiniTest::Unit::TestCase
+ class SomeObject
+ def initialize one, two
+ @one = one
+ @two = two
+ end
+
+ def == other
+ @one == other.instance_eval { @one } &&
+ @two == other.instance_eval { @two }
+ end
+ end
+
+ def test_some_object
+ so = SomeObject.new('foo', [1,2,3])
+ assert_equal so, Psych.load(Psych.dump(so))
+ end
+ end
+end