In Files

  • psych/lib/psych/visitors/to_ruby.rb
  • psych/psych_to_ruby.c

Psych::Visitors::ToRuby

This class walks a YAML AST, converting each node to Ruby

Attributes

class_loader[R]

Public Class Methods

create() click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 14
def self.create
  class_loader = ClassLoader.new
  scanner      = ScalarScanner.new class_loader
  new(scanner, class_loader)
end
            
new(ss, class_loader) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 22
def initialize ss, class_loader
  super()
  @st = {}
  @ss = ss
  @domain_types = Psych.domain_types
  @class_loader = class_loader
end
            

Public Instance Methods

accept(target) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 30
def accept target
  result = super
  return result if @domain_types.empty? || !target.tag

  key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
  key = "tag:#{key}" unless key =~ /^(tag:|x-private)/

  if @domain_types.key? key
    value, block = @domain_types[key]
    return block.call value, result
  end

  result
end
            
visit_Psych_Nodes_Alias(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 281
def visit_Psych_Nodes_Alias o
  @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" }
end
            
visit_Psych_Nodes_Document(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 273
def visit_Psych_Nodes_Document o
  accept o.root
end
            
visit_Psych_Nodes_Mapping(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 155
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(register(o, {}), o) unless o.tag

  case o.tag
  when /^!ruby\/struct:?(.*)?$/
    klass = resolve_class($1) if $1

    if klass
      s = register(o, klass.allocate)

      members = {}
      struct_members = s.members.map { |x| class_loader.symbolize x }
      o.children.each_slice(2) do |k,v|
        member = accept(k)
        value  = accept(v)
        if struct_members.include?(class_loader.symbolize(member))
          s.send("#{member}=", value)
        else
          members[member.to_s.sub(/^@/, '')] = value
        end
      end
      init_with(s, members, o)
    else
      klass = class_loader.struct
      members = o.children.map { |c| accept c }
      h = Hash[*members]
      klass.new(*h.map { |k,v|
        class_loader.symbolize k
      }).new(*h.map { |k,v| v })
    end

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

    if name == 'Complex'
      class_loader.complex
      h = Hash[*o.children.map { |c| accept c }]
      register o, Complex(h['real'], h['image'])
    elsif name == 'Rational'
      class_loader.rational
      h = Hash[*o.children.map { |c| accept c }]
      register o, Rational(h['numerator'], h['denominator'])
    else
      obj = revive((resolve_class(name) || class_loader.object), o)
      obj
    end

  when /^!(?:str|ruby\/string)(?::(.*))?/, 'tag:yaml.org,2002:str'
    klass   = resolve_class($1)
    members = {}
    string  = nil

    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)
    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'
    klass = class_loader.range
    h = Hash[*o.children.map { |c| accept c }]
    register o, klass.new(h['begin'], h['end'], h['excl'])

  when /^!ruby\/exception:?(.*)?$/
    h = Hash[*o.children.map { |c| accept c }]

    e = build_exception((resolve_class($1) || class_loader.exception),
                        h.delete('message'))
    init_with(e, h, o)

  when '!set', 'tag:yaml.org,2002:set'
    set = class_loader.psych_set.new
    @st[o.anchor] = set if o.anchor
    o.children.each_slice(2) do |k,v|
      set[accept(k)] = accept(v)
    end
    set

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

  when '!omap', 'tag:yaml.org,2002:omap'
    map = register(o, class_loader.psych_omap.new)
    o.children.each_slice(2) do |l,r|
      map[accept(l)] = accept r
    end
    map

  else
    revive_hash(register(o, {}), o)
  end
end
            
visit_Psych_Nodes_Scalar(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 119
def visit_Psych_Nodes_Scalar o
  register o, deserialize(o)
end
            
visit_Psych_Nodes_Sequence(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 123
def visit_Psych_Nodes_Sequence o
  if klass = resolve_class(Psych.load_tags[o.tag])
    instance = klass.allocate

    if instance.respond_to?(:init_with)
      coder = Psych::Coder.new(o.tag)
      coder.seq = o.children.map { |c| accept c }
      instance.init_with coder
    end

    return instance
  end

  case o.tag
  when nil
    register_empty(o)
  when '!omap', 'tag:yaml.org,2002:omap'
    map = register(o, Psych::Omap.new)
    o.children.each { |a|
      map[accept(a.children.first)] = accept a.children.last
    }
    map
  when /^!(?:seq|ruby\/array):(.*)$/
    klass = resolve_class($1)
    list  = register(o, klass.allocate)
    o.children.each { |c| list.push accept c }
    list
  else
    register_empty(o)
  end
end
            
visit_Psych_Nodes_Stream(o) click to toggle source
 
               # File psych/lib/psych/visitors/to_ruby.rb, line 277
def visit_Psych_Nodes_Stream o
  o.children.map { |c| accept c }
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus