Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more
YAMLTree builds a YAML ast given a ruby object. For example:
builder = Psych::Visitors::YAMLTree.new builder << { :foo => 'bar' } builder.tree # => #<Psych::Nodes::Stream .. }
# 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
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 42
def finish
@emitter.end_stream.tap do
@finished = true
end
end
# 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
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 48
def tree
finish unless finished?
end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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.