mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
7bb2da2e2b
commit
4c63e02740
5 changed files with 103 additions and 20 deletions
|
@ -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>
|
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)
|
* ext/dbm/dbm.c (fdbm_fetch, fdbm_key, fdbm_delete, fdbm_store)
|
||||||
|
|
|
@ -72,7 +72,9 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
def scalar value, anchor, tag, plain, quoted, style
|
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
|
end
|
||||||
|
|
||||||
def alias anchor
|
def alias anchor
|
||||||
|
|
|
@ -31,9 +31,7 @@ module Psych
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Psych_Nodes_Scalar o
|
def deserialize o
|
||||||
@st[o.anchor] = o.value if o.anchor
|
|
||||||
|
|
||||||
if klass = Psych.load_tags[o.tag]
|
if klass = Psych.load_tags[o.tag]
|
||||||
instance = klass.allocate
|
instance = klass.allocate
|
||||||
|
|
||||||
|
@ -92,6 +90,11 @@ module Psych
|
||||||
@ss.tokenize o.value
|
@ss.tokenize o.value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
private :deserialize
|
||||||
|
|
||||||
|
def visit_Psych_Nodes_Scalar o
|
||||||
|
register o, deserialize(o)
|
||||||
|
end
|
||||||
|
|
||||||
def visit_Psych_Nodes_Sequence o
|
def visit_Psych_Nodes_Sequence o
|
||||||
if klass = Psych.load_tags[o.tag]
|
if klass = Psych.load_tags[o.tag]
|
||||||
|
@ -108,15 +111,13 @@ module Psych
|
||||||
|
|
||||||
case o.tag
|
case o.tag
|
||||||
when '!omap', 'tag:yaml.org,2002:omap'
|
when '!omap', 'tag:yaml.org,2002:omap'
|
||||||
map = Psych::Omap.new
|
map = register(o, Psych::Omap.new)
|
||||||
@st[o.anchor] = map if o.anchor
|
|
||||||
o.children.each { |a|
|
o.children.each { |a|
|
||||||
map[accept(a.children.first)] = accept a.children.last
|
map[accept(a.children.first)] = accept a.children.last
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
else
|
else
|
||||||
list = []
|
list = register(o, [])
|
||||||
@st[o.anchor] = list if o.anchor
|
|
||||||
o.children.each { |c| list.push accept c }
|
o.children.each { |c| list.push accept c }
|
||||||
list
|
list
|
||||||
end
|
end
|
||||||
|
@ -135,8 +136,7 @@ module Psych
|
||||||
klass = resolve_class($1)
|
klass = resolve_class($1)
|
||||||
|
|
||||||
if klass
|
if klass
|
||||||
s = klass.allocate
|
s = register(o, klass.allocate)
|
||||||
@st[o.anchor] = s if o.anchor
|
|
||||||
|
|
||||||
members = {}
|
members = {}
|
||||||
struct_members = s.members.map { |x| x.to_sym }
|
struct_members = s.members.map { |x| x.to_sym }
|
||||||
|
@ -158,7 +158,7 @@ module Psych
|
||||||
|
|
||||||
when '!ruby/range'
|
when '!ruby/range'
|
||||||
h = Hash[*o.children.map { |c| accept c }]
|
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:?(.*)?$/
|
when /^!ruby\/exception:?(.*)?$/
|
||||||
h = Hash[*o.children.map { |c| accept c }]
|
h = Hash[*o.children.map { |c| accept c }]
|
||||||
|
@ -177,11 +177,11 @@ module Psych
|
||||||
|
|
||||||
when '!ruby/object:Complex'
|
when '!ruby/object:Complex'
|
||||||
h = Hash[*o.children.map { |c| accept c }]
|
h = Hash[*o.children.map { |c| accept c }]
|
||||||
Complex(h['real'], h['image'])
|
register o, Complex(h['real'], h['image'])
|
||||||
|
|
||||||
when '!ruby/object:Rational'
|
when '!ruby/object:Rational'
|
||||||
h = Hash[*o.children.map { |c| accept c }]
|
h = Hash[*o.children.map { |c| accept c }]
|
||||||
Rational(h['numerator'], h['denominator'])
|
register o, Rational(h['numerator'], h['denominator'])
|
||||||
|
|
||||||
when /^!ruby\/object:?(.*)?$/
|
when /^!ruby\/object:?(.*)?$/
|
||||||
name = $1 || 'Object'
|
name = $1 || 'Object'
|
||||||
|
@ -209,6 +209,11 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def register node, object
|
||||||
|
@st[node.anchor] = object if node.anchor
|
||||||
|
object
|
||||||
|
end
|
||||||
|
|
||||||
def revive_hash hash, o
|
def revive_hash hash, o
|
||||||
@st[o.anchor] = hash if o.anchor
|
@st[o.anchor] = hash if o.anchor
|
||||||
|
|
||||||
|
|
|
@ -159,13 +159,13 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Regexp o
|
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
|
end
|
||||||
|
|
||||||
def visit_DateTime o
|
def visit_DateTime o
|
||||||
formatted = format_time o.to_time
|
formatted = format_time o.to_time
|
||||||
tag = '!ruby/object:DateTime'
|
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
|
end
|
||||||
|
|
||||||
def visit_Time o
|
def visit_Time o
|
||||||
|
@ -174,7 +174,7 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Rational o
|
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,
|
'denominator', o.denominator.to_s,
|
||||||
|
@ -187,7 +187,7 @@ module Psych
|
||||||
end
|
end
|
||||||
|
|
||||||
def visit_Complex o
|
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|
|
['real', o.real.to_s, 'image', o.imag.to_s].each do |m|
|
||||||
@emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
|
@emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
|
||||||
|
@ -255,16 +255,16 @@ module Psych
|
||||||
|
|
||||||
def visit_Module o
|
def visit_Module o
|
||||||
raise TypeError, "can't dump anonymous module: #{o}" unless o.name
|
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
|
end
|
||||||
|
|
||||||
def visit_Class o
|
def visit_Class o
|
||||||
raise TypeError, "can't dump anonymous class: #{o}" unless o.name
|
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
|
end
|
||||||
|
|
||||||
def visit_Range o
|
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|
|
['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m|
|
||||||
accept m
|
accept m
|
||||||
end
|
end
|
||||||
|
|
67
test/psych/test_object_references.rb
Normal file
67
test/psych/test_object_references.rb
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue