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 43
def self.create options = {}, emitter = nil
emitter ||= TreeBuilder.new
class_loader = ClassLoader.new
ss = ScalarScanner.new class_loader
new(emitter, ss, options)
end
# 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
# 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
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 86
def finish
@emitter.end_stream.tap do
@finished = true
end
end
# 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
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 92
def tree
finish unless finished?
@emitter.root
end
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 263
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 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 235
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 211
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 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 252
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 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 245
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 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
# 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
# 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
# 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
# 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
# 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
# File psych/lib/psych/visitors/yaml_tree.rb, line 222
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 207
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 275
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
# 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
# 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
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 see Improve the docs, or visit Documenting-ruby.org.