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

ruby-changes:22281

From: tenderlove <ko1@a...>
Date: Wed, 18 Jan 2012 12:52:17 +0900 (JST)
Subject: [ruby-changes:22281] tenderlove:r34330 (trunk): * ext/psych/lib/psych/visitors/to_ruby.rb: Added support for loading

tenderlove	2012-01-18 12:52:01 +0900 (Wed, 18 Jan 2012)

  New Revision: 34330

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

  Log:
    * ext/psych/lib/psych/visitors/to_ruby.rb: Added support for loading
      subclasses of String with ivars
    * ext/psych/lib/psych/visitors/yaml_tree.rb: Added support for dumping
      subclasses of String with ivars
    * test/psych/test_string.rb: corresponding tests

  Modified files:
    trunk/ChangeLog
    trunk/ext/psych/lib/psych/visitors/to_ruby.rb
    trunk/ext/psych/lib/psych/visitors/yaml_tree.rb
    trunk/test/psych/test_string.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 34329)
+++ ChangeLog	(revision 34330)
@@ -1,3 +1,11 @@
+Wed Jan 18 12:49:15 2012  Aaron Patterson <aaron@t...>
+
+	* ext/psych/lib/psych/visitors/to_ruby.rb: Added support for loading
+	  subclasses of String with ivars
+	* ext/psych/lib/psych/visitors/yaml_tree.rb: Added support for dumping
+	  subclasses of String with ivars
+	* test/psych/test_string.rb: corresponding tests
+
 Wed Jan 18 10:39:47 2012  Aaron Patterson <aaron@t...>
 
 	* ext/psych/lib/psych/visitors/to_ruby.rb: Added ability to load array
Index: ext/psych/lib/psych/visitors/yaml_tree.rb
===================================================================
--- ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 34329)
+++ ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 34330)
@@ -245,9 +245,15 @@
         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
 
Index: ext/psych/lib/psych/visitors/to_ruby.rb
===================================================================
--- ext/psych/lib/psych/visitors/to_ruby.rb	(revision 34329)
+++ ext/psych/lib/psych/visitors/to_ruby.rb	(revision 34330)
@@ -50,8 +50,13 @@
         case o.tag
         when '!binary', 'tag:yaml.org,2002:binary'
           o.value.unpack('m').first
-        when '!str', 'tag:yaml.org,2002:str'
-          o.value
+        when /^!(?:str|ruby\/string)(?::(.*))?/, 'tag:yaml.org,2002:str'
+          klass = resolve_class($1)
+          if klass
+            klass.allocate.replace o.value
+          else
+            o.value
+          end
         when '!ruby/object:BigDecimal'
           require 'bigdecimal'
           BigDecimal._load o.value
@@ -136,9 +141,16 @@
         return revive_hash({}, o) unless o.tag
 
         case o.tag
-        when '!str', 'tag:yaml.org,2002:str'
+        when /^!(?:str|ruby\/string)(?::(.*))?/, 'tag:yaml.org,2002:str'
+          klass = resolve_class($1)
           members = Hash[*o.children.map { |c| accept c }]
           string = members.delete 'str'
+
+          if klass
+            string = klass.allocate
+            string.replace string
+          end
+
           init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
         when /^!ruby\/array:(.*)$/
           klass = resolve_class($1)
Index: test/psych/test_string.rb
===================================================================
--- test/psych/test_string.rb	(revision 34329)
+++ test/psych/test_string.rb	(revision 34330)
@@ -2,6 +2,31 @@
 
 module Psych
   class TestString < TestCase
+    class X < String
+    end
+
+    class Y < String
+      attr_accessor :val
+    end
+
+    def test_backwards_with_syck
+      x = Psych.load "--- !str:#{X.name} foo\n\n"
+      assert_equal X, x.class
+      assert_equal 'foo', x
+    end
+
+    def test_empty_subclass
+      assert_match "!ruby/string:#{X}", Psych.dump(X.new)
+      x = Psych.load Psych.dump X.new
+      assert_equal X, x.class
+    end
+
+    def test_subclass_with_attributes
+      y = Psych.load Psych.dump Y.new.tap {|y| y.val = 1}
+      assert_equal Y, y.class
+      assert_equal 1, y.val
+    end
+
     def test_string_with_base_60
       yaml = Psych.dump '01:03:05'
       assert_match "'01:03:05'", yaml

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

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