Class: Psych::ScalarScanner
Overview
Scan scalars for built in types
Constant Summary collapse
- TIME =
          Taken from yaml.org/type/timestamp.html 
- /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
- FLOAT =
          Taken from yaml.org/type/float.html 
- /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10) |[-+]?[0-9][0-9_,]*(:[0-5]?[0-9])+\.[0-9_]*(?# base 60) |[-+]?\.(inf|Inf|INF)(?# infinity) |\.(nan|NaN|NAN)(?# not a number))$/x
- INTEGER =
          Taken from yaml.org/type/int.html 
- /^(?:[-+]?0b[0-1_]+ (?# base 2) |[-+]?0[0-7_]+ (?# base 8) |[-+]?(?:0|[1-9][0-9_]*) (?# base 10) |[-+]?0x[0-9a-fA-F_]+ (?# base 16))$/x
Instance Attribute Summary collapse
- 
  
    
      #class_loader  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute class_loader. 
Instance Method Summary collapse
- 
  
    
      #initialize(class_loader)  ⇒ ScalarScanner 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    Create a new scanner. 
- 
  
    
      #parse_int(string)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Parse and return an int from string.
- 
  
    
      #parse_time(string)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Parse and return a Time from string.
- 
  
    
      #tokenize(string)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Tokenize stringreturning the Ruby object.
Constructor Details
#initialize(class_loader) ⇒ ScalarScanner
Create a new scanner
| 25 26 27 28 29 | # File 'lib/psych/scalar_scanner.rb', line 25 def initialize class_loader @string_cache = {} @symbol_cache = {} @class_loader = class_loader end | 
Instance Attribute Details
#class_loader ⇒ Object (readonly)
Returns the value of attribute class_loader.
| 22 23 24 | # File 'lib/psych/scalar_scanner.rb', line 22 def class_loader @class_loader end | 
Instance Method Details
#parse_int(string) ⇒ Object
Parse and return an int from string
| 115 116 117 118 | # File 'lib/psych/scalar_scanner.rb', line 115 def parse_int string return unless INTEGER === string Integer(string) end | 
#parse_time(string) ⇒ Object
Parse and return a Time from string
| 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | # File 'lib/psych/scalar_scanner.rb', line 122 def parse_time string klass = class_loader.load 'Time' date, time = *(string.split(/[ tT]/, 2)) (yy, m, dd) = date.match(/^(-?\d{4})-(\d{1,2})-(\d{1,2})/).captures.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 = klass.utc(yy, m, dd, hh, mm, ss, us) return time if 'Z' == md[3] return klass.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 klass.at((time - offset).to_i, us) end | 
#tokenize(string) ⇒ Object
Tokenize string returning the Ruby object
| 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # File 'lib/psych/scalar_scanner.rb', line 32 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!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/, /\n/ 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 class_loader.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] = class_loader.symbolize($2.sub(/^:/, '')) else @symbol_cache[string] = class_loader.symbolize(string.sub(/^:/, '')) 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 =~ /\A[-+]?\.\Z/ @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 |