[前][次][番号順一覧][スレッド一覧]

ruby-changes:21630

From: tenderlove <ko1@a...>
Date: Wed, 9 Nov 2011 04:54:58 +0900 (JST)
Subject: [ruby-changes:21630] tenderlove:r33679 (trunk): * ext/psych/lib/psych/tree_builder.rb: dump complex numbers,

tenderlove	2011-11-09 04:54:44 +0900 (Wed, 09 Nov 2011)

  New Revision: 33679

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33679

  Log:
    * ext/psych/lib/psych/tree_builder.rb: dump complex numbers,
      rationals, etc with reference ids.
    * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto
    * ext/psych/lib/psych/visitors/to_ruby.rb: loading complex numbers,
      rationals, etc with reference ids.
    * test/psych/test_object_references.rb: corresponding tests

  Added files:
    trunk/test/psych/test_object_references.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/psych/lib/psych/tree_builder.rb
    trunk/ext/psych/lib/psych/visitors/to_ruby.rb
    trunk/ext/psych/lib/psych/visitors/yaml_tree.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33678)
+++ ChangeLog	(revision 33679)
@@ -1,3 +1,12 @@
+Wed Nov  9 04:52:16 2011  Aaron Patterson <aaron@t...>
+
+	* ext/psych/lib/psych/tree_builder.rb: dump complex numbers,
+	  rationals, etc with reference ids.
+	* ext/psych/lib/psych/visitors/yaml_tree.rb: ditto
+	* ext/psych/lib/psych/visitors/to_ruby.rb: loading complex numbers,
+	  rationals, etc with reference ids.
+	* test/psych/test_object_references.rb: corresponding tests
+
 Tue Nov  8 23:34:37 2011  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/dbm/dbm.c (fdbm_fetch, fdbm_key, fdbm_delete, fdbm_store)
Index: ext/psych/lib/psych/visitors/yaml_tree.rb
===================================================================
--- ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 33678)
+++ ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 33679)
@@ -159,13 +159,13 @@
       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 @@
       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 @@
       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
@@ -255,16 +255,16 @@
 
       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
Index: ext/psych/lib/psych/visitors/to_ruby.rb
===================================================================
--- ext/psych/lib/psych/visitors/to_ruby.rb	(revision 33678)
+++ ext/psych/lib/psych/visitors/to_ruby.rb	(revision 33679)
@@ -31,9 +31,7 @@
         result
       end
 
-      def visit_Psych_Nodes_Scalar o
-        @st[o.anchor] = o.value if o.anchor
-
+      def deserialize o
         if klass = Psych.load_tags[o.tag]
           instance = klass.allocate
 
@@ -92,7 +90,12 @@
           @ss.tokenize o.value
         end
       end
+      private :deserialize
 
+      def visit_Psych_Nodes_Scalar o
+        register o, deserialize(o)
+      end
+
       def visit_Psych_Nodes_Sequence o
         if klass = Psych.load_tags[o.tag]
           instance = klass.allocate
@@ -108,15 +111,13 @@
 
         case o.tag
         when '!omap', 'tag:yaml.org,2002:omap'
-          map = Psych::Omap.new
-          @st[o.anchor] = map if o.anchor
+          map = register(o, Psych::Omap.new)
           o.children.each { |a|
             map[accept(a.children.first)] = accept a.children.last
           }
           map
         else
-          list = []
-          @st[o.anchor] = list if o.anchor
+          list = register(o, [])
           o.children.each { |c| list.push accept c }
           list
         end
@@ -135,8 +136,7 @@
           klass = resolve_class($1)
 
           if klass
-            s = klass.allocate
-            @st[o.anchor] = s if o.anchor
+            s = register(o, klass.allocate)
 
             members = {}
             struct_members = s.members.map { |x| x.to_sym }
@@ -158,7 +158,7 @@
 
         when '!ruby/range'
           h = Hash[*o.children.map { |c| accept c }]
-          Range.new(h['begin'], h['end'], h['excl'])
+          register o, Range.new(h['begin'], h['end'], h['excl'])
 
         when /^!ruby\/exception:?(.*)?$/
           h = Hash[*o.children.map { |c| accept c }]
@@ -177,11 +177,11 @@
 
         when '!ruby/object:Complex'
           h = Hash[*o.children.map { |c| accept c }]
-          Complex(h['real'], h['image'])
+          register o, Complex(h['real'], h['image'])
 
         when '!ruby/object:Rational'
           h = Hash[*o.children.map { |c| accept c }]
-          Rational(h['numerator'], h['denominator'])
+          register o, Rational(h['numerator'], h['denominator'])
 
         when /^!ruby\/object:?(.*)?$/
           name = $1 || 'Object'
@@ -209,6 +209,11 @@
       end
 
       private
+      def register node, object
+        @st[node.anchor] = object if node.anchor
+        object
+      end
+
       def revive_hash hash, o
         @st[o.anchor] = hash if o.anchor
 
Index: ext/psych/lib/psych/tree_builder.rb
===================================================================
--- ext/psych/lib/psych/tree_builder.rb	(revision 33678)
+++ ext/psych/lib/psych/tree_builder.rb	(revision 33679)
@@ -72,7 +72,9 @@
     end
 
     def scalar value, anchor, tag, plain, quoted, style
-      @last.children << Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
+      s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
+      @last.children << s
+      s
     end
 
     def alias anchor
Index: test/psych/test_object_references.rb
===================================================================
--- test/psych/test_object_references.rb	(revision 0)
+++ test/psych/test_object_references.rb	(revision 33679)
@@ -0,0 +1,67 @@
+require 'psych/helper'
+
+module Psych
+  class TestObjectReferences < TestCase
+    def test_range_has_references
+      assert_reference_trip 1..2
+    end
+
+    def test_module_has_references
+      assert_reference_trip Psych
+    end
+
+    def test_class_has_references
+      assert_reference_trip TestObjectReferences
+    end
+
+    def test_rational_has_references
+      assert_reference_trip Rational('1.2')
+    end
+
+    def test_complex_has_references
+      assert_reference_trip Complex(1, 2)
+    end
+
+    def test_datetime_has_references
+      assert_reference_trip DateTime.now
+    end
+
+    def assert_reference_trip obj
+      yml = Psych.dump([obj, obj])
+      assert_match(/\*\d+/, yml)
+      data = Psych.load yml
+      assert_equal data.first.object_id, data.last.object_id
+    end
+
+    def test_float_references
+      data = Psych.load <<-eoyml
+--- 
+- &name 1.2
+- *name
+      eoyml
+      assert_equal data.first, data.last
+      assert_equal data.first.object_id, data.last.object_id
+    end
+
+    def test_binary_references
+      data = Psych.load <<-eoyml
+---
+- &name !binary |-
+  aGVsbG8gd29ybGQh
+- *name
+      eoyml
+      assert_equal data.first, data.last
+      assert_equal data.first.object_id, data.last.object_id
+    end
+
+    def test_regexp_references
+      data = Psych.load <<-eoyml
+--- 
+- &name !ruby/regexp /pattern/i
+- *name
+      eoyml
+      assert_equal data.first, data.last
+      assert_equal data.first.object_id, data.last.object_id
+    end
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]