In Files

  • psych/lib/psych/visitors/yaml_tree.rb
  • 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 15
def initialize options = {}, emitter = TreeBuilder.new, ss = ScalarScanner.new
  super()
  @started  = false
  @finished = false
  @emitter  = emitter
  @st       = {}
  @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 72
def accept target
  # return any aliases we find
  if @st.key? target.object_id
    oid         = target.object_id
    node        = @st[oid]
    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 42
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 52
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
end
            
Also aliased as: <<
start(encoding = Nodes::Stream::UTF8) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 36
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 48
def tree
  finish unless finished?
end
            
visit_Array(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 310
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 218
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 272
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 190
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 166
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 143
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 207
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 285
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 200
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 267
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 320
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 115
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 107
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 299
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 277
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 177
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 162
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 229
def visit_String o
  plain = false
  quote = false
  style = Nodes::Scalar::ANY

  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
  else
    str   = o
    tag   = nil
    quote = !(String === @ss.tokenize(o))
    plain = !quote
  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 129
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 324
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 172
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