class 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
create
(options = {})
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 44 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, ss, options)
Calls superclass method
BasicObject::new
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 51 def initialize emitter, ss, options super() @started = false @finished = false @emitter = emitter @st = Registrar.new @ss = ss @options = options @line_width = options[:line_width] if @line_width && @line_width < 0 if @line_width == -1 # Treat -1 as unlimited line-width, same as libyaml does. @line_width = nil else fail(ArgumentError, "Invalid line_width #{@line_width}, must be non-negative or -1 for unlimited.") end end @stringify_names = options[:stringify_names] @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.compare_by_identity end
Public Instance Methods
accept
(target)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 119 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?(:encode_with) dump_coder target else send(@dispatch_cache[target.class], target) end end
finish
()
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 88 def finish @emitter.end_stream.tap do @finished = true end end
push
(object)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 99 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 82 def start encoding = Nodes::Stream::UTF8 @emitter.start_stream(encoding).tap do @started = true end end
tree
()
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 94 def tree finish unless finished? @emitter.root end
visit_Array
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 347 def visit_Array o if o.class == ::Array visit_Enumerator o else visit_array_subclass o end end
visit_BasicObject
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 373 def visit_BasicObject o tag = Psych.dump_tags[o.class] tag ||= "!ruby/marshalable:#{o.class.name}" map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) register(o, map) o.marshal_dump.each(&method(:accept)) @emitter.end_mapping end
visit_BigDecimal
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 247 def visit_BigDecimal o @emitter.scalar o._dump, nil, '!ruby/object:BigDecimal', false, false, Nodes::Scalar::ANY end
visit_Class
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 310 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 220 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 191 def visit_Date o register o, visit_Integer(o.gregorian) end
visit_DateTime
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 195 def visit_DateTime o t = o.italy formatted = format_time t, t.offset.zero? tag = '!ruby/object:DateTime' register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY) end
visit_Encoding
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 144 def visit_Encoding o tag = "!ruby/encoding" @emitter.scalar o.name, nil, tag, false, false, Nodes::Scalar::ANY end
visit_Enumerator
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 355 def visit_Enumerator o register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) o.each { |c| accept c } @emitter.end_sequence end
visit_Exception
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 179 def visit_Exception o dump_exception o, o.message.to_s end
visit_Float
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 236 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 323 def visit_Hash o if o.class == ::Hash register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @emitter.end_mapping else visit_hash_subclass o end end
visit_Integer
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 230 def visit_Integer o @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY end
Also aliased as: visit_TrueClass, visit_FalseClass
visit_Module
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 305 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_NameError
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 183 def visit_NameError o dump_exception o, o.message.to_s end
visit_NilClass
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 361 def visit_NilClass o @emitter.scalar('', nil, 'tag:yaml.org,2002:null', true, false, Nodes::Scalar::ANY) end
visit_Object
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 149 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
Also aliased as: visit_Delegator
visit_Psych_Omap
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 136 def visit_Psych_Omap o seq = @emitter.start_sequence(nil, 'tag:yaml.org,2002:omap', false, Nodes::Sequence::BLOCK) register(o, seq) o.each { |k,v| visit_Hash k => v } @emitter.end_sequence end
visit_Psych_Set
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 336 def visit_Psych_Set o register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @emitter.end_mapping end
visit_Range
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 315 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 207 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)
# File ext/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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 251 def visit_String o plain = true quote = true style = Nodes::Scalar::PLAIN tag = nil if binary?(o) o = [o].pack('m0') 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.match?(/\n(?!\Z)/) # match \n except blank line at the end of string style = Nodes::Scalar::LITERAL elsif o == '<<' style = Nodes::Scalar::SINGLE_QUOTED tag = 'tag:yaml.org,2002:str' plain = false quote = false elsif o == 'y' || o == 'Y' || o == 'n' || o == 'N' style = Nodes::Scalar::DOUBLE_QUOTED elsif @line_width && o.length > @line_width style = Nodes::Scalar::FOLDED elsif o.match?(/^[^[:word:]][^"]*$/) style = Nodes::Scalar::DOUBLE_QUOTED elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o) style = Nodes::Scalar::SINGLE_QUOTED end is_primitive = o.class == ::String ivars = is_primitive ? [] : o.instance_variables if ivars.empty? unless is_primitive tag = "!ruby/string:#{o.class}" plain = false quote = false end @emitter.scalar o, nil, tag, plain, quote, style else maptag = '!ruby/string'.dup 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 o, nil, tag, plain, quote, style dump_ivars o @emitter.end_mapping end end
visit_Struct
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 165 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)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 365 def visit_Symbol o if o.empty? @emitter.scalar "", nil, '!ruby/symbol', false, false, Nodes::Scalar::ANY else @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY end end
visit_Time
(o)
# File ext/psych/lib/psych/visitors/yaml_tree.rb, line 202 def visit_Time o formatted = format_time o register o, @emitter.scalar(formatted, nil, nil, true, false, Nodes::Scalar::ANY) end