Skip to content

Commit

Permalink
Restructured node mapping so common cases are evaluated first, saving…
Browse files Browse the repository at this point in the history
… unnecessary comparisons.
  • Loading branch information
nirvdrum committed Oct 13, 2012
1 parent 4be2aef commit 2ceb7b6
Showing 1 changed file with 37 additions and 35 deletions.
72 changes: 37 additions & 35 deletions lib/psych/visitors/to_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,28 +141,6 @@ def visit_Psych_Nodes_Mapping o
return revive_hash({}, o) unless o.tag

case o.tag
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.replace string
register(o, string)
end

init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
when /^!ruby\/array:(.*)$/
klass = resolve_class($1)
list = register(o, klass.allocate)

members = Hash[o.children.map { |c| accept c }.each_slice(2).to_a]
list.replace members['internal']

members['ivars'].each do |ivar, v|
list.instance_variable_set ivar, v
end
list
when /^!ruby\/struct:?(.*)?$/
klass = resolve_class($1)

Expand All @@ -187,6 +165,43 @@ def visit_Psych_Nodes_Mapping o
Struct.new(*h.map { |k,v| k.to_sym }).new(*h.map { |k,v| v })
end

when /^!ruby\/object:?(.*)?$/
name = $1 || 'Object'

if name == 'Complex'
h = Hash[*o.children.map { |c| accept c }]
register o, Complex(h['real'], h['image'])
elsif name == 'Rational'
h = Hash[*o.children.map { |c| accept c }]
register o, Rational(h['numerator'], h['denominator'])
else
obj = revive((resolve_class(name) || Object), o)
obj
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'

if klass
string = klass.allocate.replace string
register(o, string)
end

init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o)
when /^!ruby\/array:(.*)$/
klass = resolve_class($1)
list = register(o, klass.allocate)

members = Hash[o.children.map { |c| accept c }.each_slice(2).to_a]
list.replace members['internal']

members['ivars'].each do |ivar, v|
list.instance_variable_set ivar, v
end
list

when '!ruby/range'
h = Hash[*o.children.map { |c| accept c }]
register o, Range.new(h['begin'], h['end'], h['excl'])
Expand All @@ -206,19 +221,6 @@ def visit_Psych_Nodes_Mapping o
end
set

when '!ruby/object:Complex'
h = Hash[*o.children.map { |c| accept c }]
register o, Complex(h['real'], h['image'])

when '!ruby/object:Rational'
h = Hash[*o.children.map { |c| accept c }]
register o, Rational(h['numerator'], h['denominator'])

when /^!ruby\/object:?(.*)?$/
name = $1 || 'Object'
obj = revive((resolve_class(name) || Object), o)
obj

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

Expand Down

0 comments on commit 2ceb7b6

Please sign in to comment.