In Files

  • psych/lib/psych/scalar_scanner.rb

Psych::ScalarScanner

Scan scalars for built in types

Public Class Methods

new() click to toggle source

Create a new scanner

 
               # File psych/lib/psych/scalar_scanner.rb, line 23
def initialize
  @string_cache = {}
  @symbol_cache = {}
end
            

Public Instance Methods

parse_int(string) click to toggle source

Parse and return an int from string

 
               # File psych/lib/psych/scalar_scanner.rb, line 112
def parse_int string
  return unless INTEGER === string
  Integer(string)
end
            
parse_time(string) click to toggle source

Parse and return a Time from string

 
               # File psych/lib/psych/scalar_scanner.rb, line 119
def parse_time string
  date, time = *(string.split(/[ tT]/, 2))
  (yy, m, dd) = date.split('-').map { |x| x.to_i }
  md = time.match(/(\d+:\d+:\d+)(?:\.(\d*))?\s*(Z|[-+]\d+(:\d\d)?)?/)

  (hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
  us = (md[2] ? Rational("0.#{md[2]}") : 0) * 1000000

  time = Time.utc(yy, m, dd, hh, mm, ss, us)

  return time if 'Z' == md[3]
  return Time.at(time.to_i, us) unless md[3]

  tz = md[3].match(/^([+\-]?\d{1,2})\:?(\d{1,2})?$/)[1..-1].compact.map { |digit| Integer(digit, 10) }
  offset = tz.first * 3600

  if offset < 0
    offset -= ((tz[1] || 0) * 60)
  else
    offset += ((tz[1] || 0) * 60)
  end

  Time.at((time - offset).to_i, us)
end
            
tokenize(string) click to toggle source

Tokenize string returning the ruby object

 
               # File psych/lib/psych/scalar_scanner.rb, line 29
def tokenize string
  return nil if string.empty?
  return string if @string_cache.key?(string)
  return @symbol_cache[string] if @symbol_cache.key?(string)

  case string
  # Check for a String type, being careful not to get caught by hash keys, hex values, and
  # special floats (e.g., -.inf).
  when /^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\~;=]+/
    if string.length > 5
      @string_cache[string] = true
      return string
    end

    case string
    when /^[^ytonf~]/i
      @string_cache[string] = true
      string
    when '~', /^null$/i
      nil
    when /^(yes|true|on)$/i
      true
    when /^(no|false|off)$/i
      false
    else
      @string_cache[string] = true
      string
    end
  when TIME
    begin
      parse_time string
    rescue ArgumentError
      string
    end
  when /^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/
    require 'date'
    begin
      Date.strptime(string, '%Y-%m-%d')
    rescue ArgumentError
      string
    end
  when /^\.inf$/i
    Float::INFINITY
  when /^-\.inf$/i
    -Float::INFINITY
  when /^\.nan$/i
    Float::NAN
  when /^:./
    if string =~ /^:(["'])(.*)\1/
      @symbol_cache[string] = $2.sub(/^:/, '').to_sym
    else
      @symbol_cache[string] = string.sub(/^:/, '').to_sym
    end
  when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+$/
    i = 0
    string.split(':').each_with_index do |n,e|
      i += (n.to_i * 60 ** (e - 2).abs)
    end
    i
  when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*$/
    i = 0
    string.split(':').each_with_index do |n,e|
      i += (n.to_f * 60 ** (e - 2).abs)
    end
    i
  when FLOAT
    if string == '.'
      @string_cache[string] = true
      string
    else
      Float(string.gsub(/[,_]|\.$/, ''))
    end
  else
    int = parse_int string.gsub(/[,_]/, '')
    return int if int

    @string_cache[string] = true
    string
  end
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.

blog comments powered by Disqus