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 .. }

Constants

BINARY_RANGE
NULL

FIXME: Remove the index and count checks in Psych 3.0

WS_RANGE

Attributes

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

Public Class Methods

create(options = {}) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 43
def self.create options = {}, emitter = nil
  emitter      ||= TreeBuilder.new
  class_loader = ClassLoader.new
  ss           = ScalarScanner.new class_loader
  new(emitter, ss, options)
end
            
new(emitter = nil, ss = nil, options = nil) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 50
def self.new emitter = nil, ss = nil, options = nil
  return super if emitter && ss && options

  if $VERBOSE
    warn "This API is deprecated, please pass an emitter, scalar scanner, and options or call #{self}.create() (#{caller.first})"
  end
  create emitter, ss
end
            
new(emitter, ss, options) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 59
def initialize emitter, ss, options
  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 117
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 86
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 97
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 80
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 92
def tree
  finish unless finished?
  @emitter.root
end
            
visit_Array(o) click to toggle source
 
               # File psych/lib/psych/visitors/yaml_tree.rb, line 361
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 267
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 323
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 239
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 211
def visit_DateTime o
  formatted = if o.offset.zero?
                o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze)
              else
                o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
              end
  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 188
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 256
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 336
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 249
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 318
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 371
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 160
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 152
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 350
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 328
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 226
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 207
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 271
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
  elsif o =~ /^\W/
    style = Nodes::Scalar::DOUBLE_QUOTED
  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}"
      plain = false
      quote = false
    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 174
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 375
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 221
def visit_Time o
  formatted = format_time o
  register 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