Class: Tins::Unit::UnitParser
- Defined in:
- lib/tins/unit.rb
Overview
A parser for unit specifications that extends StringScanner
This class is responsible for parsing strings that contain numerical values followed by unit specifications, supporting various prefix types and unit formats for flexible unit parsing.
Constant Summary collapse
- NUMBER =
A regular expression matching a number.
/([+-]? (?:0|[1-9]\d*) (?: \.\d+(?i:e[+-]?\d+) | \.\d+ | (?i:e[+-]?\d+) )? )/x
Instance Attribute Summary collapse
-
#number ⇒ Object
readonly
The number reader method returns the value of the number attribute.
Instance Method Summary collapse
-
#initialize(source, unit, prefixes = nil) ⇒ UnitParser
constructor
The initialize method sets up a new UnitParser instance with the given source string, unit identifier, and optional prefixes configuration.
-
#parse ⇒ Object
The parse method is intended to be overridden by subclasses to provide specific parsing functionality.
-
#scan(re) ⇒ String?
The scan method scans a regular expression against the current string scanner state.
-
#scan_char(char) ⇒ String?
The scan_char method attempts to match a character pattern against the current string scanner state.
-
#scan_number ⇒ Object
The scan_number method parses a number from the current string scanner state and multiplies the internal number value by it.
-
#scan_unit ⇒ Object
The scan_unit method attempts to match unit patterns against the current string and updates the internal number value by multiplying it with the corresponding prefix multiplier.
-
#unit_re(prefixes, unit) ⇒ Regexp
private
The unit_re method creates a regular expression for matching units with prefixes.
Constructor Details
#initialize(source, unit, prefixes = nil) ⇒ UnitParser
The initialize method sets up a new UnitParser instance with the given source string, unit identifier, and optional prefixes configuration.
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/tins/unit.rb', line 112 def initialize(source, unit, prefixes = nil) super source if prefixes @unit_re = unit_re(Tins::Unit.prefixes(prefixes), unit) @unit_lc_re = @unit_uc_re = nil else @unit_lc_re = unit_re(Tins::Unit.prefixes(:lc), unit) @unit_uc_re = unit_re(Tins::Unit.prefixes(:uc), unit) @unit_re = nil end @number = 1.0 end |
Instance Attribute Details
#number ⇒ Object (readonly)
The number reader method returns the value of the number attribute.
151 152 153 |
# File 'lib/tins/unit.rb', line 151 def number @number end |
Instance Method Details
#parse ⇒ Object
The parse method is intended to be overridden by subclasses to provide specific parsing functionality.
204 205 206 |
# File 'lib/tins/unit.rb', line 204 def parse raise NotImplementedError end |
#scan(re) ⇒ String?
The scan method scans a regular expression against the current string scanner state.
This method delegates to the parent StringScanner’s scan method, but includes a guard clause to return early if the provided regular expression is nil.
162 163 164 165 |
# File 'lib/tins/unit.rb', line 162 def scan(re) re.nil? and return super end |
#scan_char(char) ⇒ String?
The scan_char method attempts to match a character pattern against the current string scanner state.
196 197 198 |
# File 'lib/tins/unit.rb', line 196 def scan_char(char) scan(/#{char}/) or return end |
#scan_number ⇒ Object
The scan_number method parses a number from the current string scanner state and multiplies the internal number value by it.
169 170 171 172 |
# File 'lib/tins/unit.rb', line 169 def scan_number scan(NUMBER) or return @number *= BigDecimal(self[1]) end |
#scan_unit ⇒ Object
The scan_unit method attempts to match unit patterns against the current string and updates the internal number value by multiplying it with the corresponding prefix multiplier
177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/tins/unit.rb', line 177 def scan_unit case when scan(@unit_re) prefix = @unit_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier when scan(@unit_lc_re) prefix = @unit_lc_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier when scan(@unit_uc_re) prefix = @unit_uc_re.prefixes.find { |pre| pre.name == self[1] } or return @number *= prefix.multiplier end end |
#unit_re(prefixes, unit) ⇒ Regexp (private)
The unit_re method creates a regular expression for matching units with prefixes
This method constructs a regular expression pattern that can match unit strings including their associated prefixes, which is useful for parsing formatted unit specifications in text.
136 137 138 139 140 141 142 143 144 |
# File 'lib/tins/unit.rb', line 136 def unit_re(prefixes, unit) re = Regexp.new( "(#{prefixes.reverse.map { |pre| Regexp.quote(pre.name) } * ?|})(#{unit})" ) re.singleton_class.class_eval do define_method(:prefixes) { prefixes } end re end |