* 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

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2011-11-08 19:54:44 +00:00
Родитель 7bb2da2e2b
Коммит 4c63e02740
5 изменённых файлов: 103 добавлений и 20 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Wed Nov 9 04:52:16 2011 Aaron Patterson <aaron@tenderlovemaking.com>
* 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@ruby-lang.org>
* ext/dbm/dbm.c (fdbm_fetch, fdbm_key, fdbm_delete, fdbm_store)

Просмотреть файл

@ -72,7 +72,9 @@ module Psych
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

Просмотреть файл

@ -31,9 +31,7 @@ module Psych
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,6 +90,11 @@ module Psych
@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]
@ -108,15 +111,13 @@ module Psych
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 @@ module Psych
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 @@ module Psych
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 @@ module Psych
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 @@ module Psych
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

Просмотреть файл

@ -159,13 +159,13 @@ module Psych
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 @@ module Psych
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 @@ module Psych
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 @@ module Psych
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

Просмотреть файл

@ -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