summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-04-05 10:12:02 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-04-05 10:12:02 -0700
commit0c82d6d009eceb2bac048c2262f68c1fc494dde9 (patch)
treef1a4131230d187f71f70d90d12dd0264cad85f6e
parentb4537454d9da6e901dcacf4c4e36de08095f79a3 (diff)
downloadpsych-0c82d6d009eceb2bac048c2262f68c1fc494dde9.zip
* ext/psych/lib/psych/visitors/to_ruby.rb: correctly register
self-referential strings. Fixes tenderlove/psych #135 * test/psych/test_string.rb: appropriate test.
-rw-r--r--CHANGELOG.rdoc7
-rw-r--r--lib/psych/visitors/to_ruby.rb24
-rw-r--r--test/psych/test_string.rb25
3 files changed, 49 insertions, 7 deletions
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc
index 9f28f80..2df0bb5 100644
--- a/CHANGELOG.rdoc
+++ b/CHANGELOG.rdoc
@@ -1,3 +1,10 @@
+Sat Apr 6 02:06:04 2013 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/visitors/to_ruby.rb: correctly register
+ self-referential strings. Fixes tenderlove/psych #135
+
+ * test/psych/test_string.rb: appropriate test.
+
Fri Mar 1 09:15:00 2013 Zachary Scott <zachary@zacharyscott.net>
* lib/psych.rb: specify in rdoc what object is returned in parser
diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb
index 9ccf420..b59bc38 100644
--- a/lib/psych/visitors/to_ruby.rb
+++ b/lib/psych/visitors/to_ruby.rb
@@ -180,15 +180,25 @@ module Psych
end
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'
+ klass = resolve_class($1)
+ members = {}
+ string = nil
- if klass
- string = klass.allocate.replace string
- register(o, string)
- end
+ o.children.each_slice(2) do |k,v|
+ key = accept k
+ value = accept v
+ if key == 'str'
+ if klass
+ string = klass.allocate.replace value
+ else
+ string = value
+ end
+ register(o, string)
+ else
+ members[key] = value
+ end
+ end
init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
when /^!ruby\/array:(.*)$/
klass = resolve_class($1)
diff --git a/test/psych/test_string.rb b/test/psych/test_string.rb
index a298831..0bdba18 100644
--- a/test/psych/test_string.rb
+++ b/test/psych/test_string.rb
@@ -15,6 +15,31 @@ module Psych
end
end
+ def test_string_subclass_with_anchor
+ y = Psych.load <<-eoyml
+---
+body:
+ string: &70121654388580 !ruby/string
+ str: ! 'foo'
+ x:
+ body: *70121654388580
+ eoyml
+ assert_equal({"body"=>{"string"=>"foo", "x"=>{"body"=>"foo"}}}, y)
+ end
+
+ def test_self_referential_string
+ y = Psych.load <<-eoyml
+---
+string: &70121654388580 !ruby/string
+ str: ! 'foo'
+ body: *70121654388580
+ eoyml
+
+ assert_equal({"string"=>"foo"}, y)
+ value = y['string']
+ assert_equal value, value.instance_variable_get(:@body)
+ end
+
def test_another_subclass_with_attributes
y = Psych.load Psych.dump Y.new("foo").tap {|y| y.val = 1}
assert_equal "foo", y