Skip to content

Commit

Permalink
* ext/psych/lib/psych/visitors/to_ruby.rb: process merge keys before
Browse files Browse the repository at this point in the history
  reviving objects. Fixes GH psych #168
* test/psych/test_merge_keys.rb: test for change
  #168

Fixes #169
  • Loading branch information
tenderlove committed Nov 5, 2013
1 parent 41152b9 commit 1003a03
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Wed Nov 6 04:14:25 2013 Aaron Patterson <aaron@tenderlovemaking.com>

* ext/psych/lib/psych/visitors/to_ruby.rb: process merge keys before
reviving objects. Fixes GH psych #168
* test/psych/test_merge_keys.rb: test for change
https://github.com/tenderlove/psych/issues/168

Wed Oct 30 03:25:10 2013 Aaron Patterson <aaron@tenderlovemaking.com>

* ext/psych/lib/psych/visitors/yaml_tree.rb: make less garbage when
Expand Down
14 changes: 5 additions & 9 deletions lib/psych/visitors/to_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def visit_Psych_Nodes_Mapping o
if Psych.load_tags[o.tag]
return revive(resolve_class(Psych.load_tags[o.tag]), o)
end
return revive_hash({}, o) unless o.tag
return revive_hash(register(o, {}), o) unless o.tag

case o.tag
when /^!ruby\/struct:?(.*)?$/
Expand Down Expand Up @@ -256,7 +256,7 @@ def visit_Psych_Nodes_Mapping o
set

when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/
revive_hash resolve_class($1).new, o
revive_hash register(o, resolve_class($1).new), o

when '!omap', 'tag:yaml.org,2002:omap'
map = register(o, class_loader.psych_omap.new)
Expand All @@ -266,7 +266,7 @@ def visit_Psych_Nodes_Mapping o
map

else
revive_hash({}, o)
revive_hash(register(o, {}), o)
end
end

Expand Down Expand Up @@ -295,8 +295,6 @@ def register_empty object
end

def revive_hash hash, o
@st[o.anchor] = hash if o.anchor

o.children.each_slice(2) { |k,v|
key = accept(k)
val = accept(v)
Expand Down Expand Up @@ -334,10 +332,8 @@ def merge_key hash, key, val
end

def revive klass, node
s = klass.allocate
@st[node.anchor] = s if node.anchor
h = Hash[*node.children.map { |c| accept c }]
init_with(s, h, node)
s = register(node, klass.allocate)
init_with(s, revive_hash({}, node), node)
end

def init_with o, h, node
Expand Down
18 changes: 18 additions & 0 deletions test/psych/test_merge_keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

module Psych
class TestMergeKeys < TestCase
class Product
attr_reader :bar
end

def test_mergekey_with_object
s = <<-eoyml
foo: &foo
bar: 10
product:
!ruby/object:#{Product.name}
<<: *foo
eoyml
hash = Psych.load s
assert_equal({"bar" => 10}, hash["foo"])
product = hash["product"]
assert_equal 10, product.bar
end

def test_merge_nil
yaml = <<-eoyml
defaults: &defaults
Expand Down

0 comments on commit 1003a03

Please sign in to comment.