In Files

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

Psych::Visitors::YAMLTree

YAMLTree builds a YAML ast given a ruby object. For example:

builder = Psych::Visitors::YAMLTree.new
builder << { :foo => 'bar' }
builder.tree # => #<Psych::Nodes::Stream .. }

Attributes

finished[R]
finished?[R]
started[R]
started?[R]

Public Class Methods

new(options = {}) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 39
def initialize options = {}, emitter = TreeBuilder.new, ss = ScalarScanner.new
  super()
  @started  = false
  @finished = false
  @emitter  = emitter
  @st       = Registrar.new
  @ss       = ss
  @options  = options
  @coders   = []

  @dispatch_cache = Hash.new do |h,klass|
    method = "visit_#{(klass.name || '').split('::').join('_')}"

    method = respond_to?(method) ? method : h[klass.superclass]

    raise(TypeError, "Can't dump #{target.class}") unless method

    h[klass] = method
  end
end
            

Public Instance Methods

<<(object) click to toggle source
Alias for: push
accept(target) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 97
def accept target
  # return any aliases we find
  if @st.key? target
    oid         = @st.id_for target
    node        = @st.node_for target
    anchor      = oid.to_s
    node.anchor = anchor
    return @emitter.alias anchor
  end

  if target.respond_to?(:to_yaml)
    begin
      loc = target.method(:to_yaml).source_location.first
      if loc !~ /(syck\/rubytypes.rb|psych\/core_ext.rb)/
        unless target.respond_to?(:encode_with)
          if $VERBOSE
            warn "implementing to_yaml is deprecated, please implement \"encode_with\""
          end

          target.to_yaml(:nodump => true)
        end
      end
    rescue
      # public_method or source_location might be overridden,
      # and it's OK to skip it since it's only to emit a warning
    end
  end

  if target.respond_to?(:encode_with)
    dump_coder target
  else
    send(@dispatch_cache[target.class], target)
  end
end
            
finish() click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 66
def finish
  @emitter.end_stream.tap do
    @finished = true
  end
end
            
push(object) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 77
def push object
  start unless started?
  version = []
  version = [1,1] if @options[:header]

  case @options[:version]
  when Array
    version = @options[:version]
  when String
    version = @options[:version].split('.').map { |x| x.to_i }
  else
    version = [1,1]
  end if @options.key? :version

  @emitter.start_document version, [], false
  accept object
  @emitter.end_document !@emitter.streaming?
end
            
Also aliased as: <<
start(encoding = Nodes::Stream::UTF8) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 60
def start encoding = Nodes::Stream::UTF8
  @emitter.start_stream(encoding).tap do
    @started = true
  end
end
            
tree() click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 72
def tree
  finish unless finished?
  @emitter.root
end
            
visit_Array(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 341
def visit_Array o
  if o.class == ::Array
    register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK)
    o.each { |c| accept c }
    @emitter.end_sequence
  else
    visit_array_subclass o
  end
end
            
visit_BigDecimal(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 243
def visit_BigDecimal o
  @emitter.scalar o._dump, nil, '!ruby/object:BigDecimal', false, false, Nodes::Scalar::ANY
end
            
visit_Class(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 303
def visit_Class o
  raise TypeError, "can't dump anonymous class: #{o}" unless o.name
  register o, @emitter.scalar(o.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED)
end
            
visit_Complex(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 215
def visit_Complex o
  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
  end

  @emitter.end_mapping
end
            
visit_Date(o) click to toggle source
Alias for: visit_Integer
visit_DateTime(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 191
def visit_DateTime o
  formatted = format_time o.to_time
  tag = '!ruby/object:DateTime'
  register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
end
            
visit_Exception(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 168
def visit_Exception o
  tag = ['!ruby/exception', o.class.name].join ':'

  @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK

  {
    'message'   => private_iv_get(o, 'mesg'),
    'backtrace' => private_iv_get(o, 'backtrace'),
  }.each do |k,v|
    next unless v
    @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
    accept v
  end

  dump_ivars o

  @emitter.end_mapping
end
            
visit_FalseClass(o) click to toggle source
Alias for: visit_Integer
visit_Float(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 232
def visit_Float o
  if o.nan?
    @emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY
  elsif o.infinite?
    @emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'),
      nil, nil, true, false, Nodes::Scalar::ANY)
  else
    @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
  end
end
            
visit_Hash(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 316
def visit_Hash o
  tag      = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}"
  implicit = !tag

  register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK))

  o.each do |k,v|
    accept k
    accept v
  end

  @emitter.end_mapping
end
            
visit_Integer(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 225
def visit_Integer o
  @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
end
            
visit_Module(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 298
def visit_Module o
  raise TypeError, "can't dump anonymous module: #{o}" unless o.name
  register o, @emitter.scalar(o.name, nil, '!ruby/module', false, false, Nodes::Scalar::SINGLE_QUOTED)
end
            
visit_NilClass(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 351
def visit_NilClass o
  @emitter.scalar('', nil, 'tag:yaml.org,2002:null', true, false, Nodes::Scalar::ANY)
end
            
visit_Object(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 140
def visit_Object o
  tag = Psych.dump_tags[o.class]
  unless tag
    klass = o.class == Object ? nil : o.class.name
    tag   = ['!ruby/object', klass].compact.join(':')
  end

  map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
  register(o, map)

  dump_ivars o
  @emitter.end_mapping
end
            
visit_Psych_Omap(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 132
def visit_Psych_Omap o
  seq = @emitter.start_sequence(nil, '!omap', false, Nodes::Sequence::BLOCK)
  register(o, seq)

  o.each { |k,v| visit_Hash k => v }
  @emitter.end_sequence
end
            
visit_Psych_Set(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 330
def visit_Psych_Set o
  register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK))

  o.each do |k,v|
    accept k
    accept v
  end

  @emitter.end_mapping
end
            
visit_Range(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 308
def visit_Range o
  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
  @emitter.end_mapping
end
            
visit_Rational(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 202
def visit_Rational o
  register o, @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK)

  [
    'denominator', o.denominator.to_s,
    'numerator', o.numerator.to_s
  ].each do |m|
    @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY
  end

  @emitter.end_mapping
end
            
visit_Regexp(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 187
def visit_Regexp o
  register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
end
            
visit_String(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 255
def visit_String o
  plain = true
  quote = true
  style = Nodes::Scalar::PLAIN
  tag   = nil
  str   = o

  if binary?(o)
    str   = [o].pack('m').chomp
    tag   = '!binary' # FIXME: change to below when syck is removed
    #tag   = 'tag:yaml.org,2002:binary'
    style = Nodes::Scalar::LITERAL
    plain = false
    quote = false
  elsif o =~ /\n/
    style = Nodes::Scalar::LITERAL
  else
    unless String === @ss.tokenize(o)
      style = Nodes::Scalar::SINGLE_QUOTED
    end
  end

  ivars = find_ivars o

  if ivars.empty?
    unless o.class == ::String
      tag = "!ruby/string:#{o.class}"
    end
    @emitter.scalar str, nil, tag, plain, quote, style
  else
    maptag = '!ruby/string'
    maptag << ":#{o.class}" unless o.class == ::String

    register o, @emitter.start_mapping(nil, maptag, false, Nodes::Mapping::BLOCK)
    @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY
    @emitter.scalar str, nil, tag, plain, quote, style

    dump_ivars o

    @emitter.end_mapping
  end
end
            
visit_Struct(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 154
def visit_Struct o
  tag = ['!ruby/struct', o.class.name].compact.join(':')

  register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
  o.members.each do |member|
    @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY
    accept o[member]
  end

  dump_ivars o

  @emitter.end_mapping
end
            
visit_Symbol(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 355
def visit_Symbol o
  @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY
end
            
visit_Time(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 197
def visit_Time o
  formatted = format_time o
  @emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY
end
            
visit_TrueClass(o) click to toggle source
Alias for: visit_Integer

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