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 17
def initialize
  @string_cache = {}
end
            

Public Instance Methods

parse_time(string) click to toggle source

Parse and return a Time from string

 
               # File psych/lib/psych/scalar_scanner.rb, line 103
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 22
def tokenize string
  return nil if string.empty?
  return string if @string_cache.key?(string)

  case string
  when /^[A-Za-z~]/
    if string.length > 5
      @string_cache[string] = true
      return string
    end

    case string
    when /^[^ytonf~]/
      @string_cache[string] = true
      string
    when '~', /^null$/
      nil
    when /^(yes|true|on)$/
      true
    when /^(no|false|off)$/
      false
    else
      @string_cache[string] = true
      string
    end
  when TIME
    parse_time string
  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$/
    1 / 0.0
  when /^-\.inf$/
    -1 / 0.0
  when /^\.nan$/
    0.0 / 0.0
  when /^:./
    if string =~ /^:(["'])(.*)\1/
      $2.sub(/^:/, '').to_sym
    else
      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
    begin
      return Float(string.gsub(/[,_]/, ''))
    rescue ArgumentError
    end

    @string_cache[string] = true
    string
  else
    if string.count('.') < 2
      begin
        return Integer(string.gsub(/[,_]/, ''))
      rescue ArgumentError
      end
    end

    @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