Class: Tins::Unit::UnitParser

Inherits:
StringScanner
  • Object
show all
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

Instance Method Summary collapse

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.



128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/tins/unit.rb', line 128

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

#numberObject (readonly)

The number reader method returns the value of the number attribute.



167
168
169
# File 'lib/tins/unit.rb', line 167

def number
  @number
end

Instance Method Details

#parseObject

The parse method is intended to be overridden by subclasses to provide specific parsing functionality.

Raises:

  • (NotImplementedError)


220
221
222
# File 'lib/tins/unit.rb', line 220

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.



178
179
180
181
# File 'lib/tins/unit.rb', line 178

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.



212
213
214
# File 'lib/tins/unit.rb', line 212

def scan_char(char)
  scan(/#{char}/) or return
end

#scan_numberObject

The scan_number method parses a number from the current string scanner state and multiplies the internal number value by it.



185
186
187
188
# File 'lib/tins/unit.rb', line 185

def scan_number
  scan(NUMBER) or return
  @number *= BigDecimal(self[1])
end

#scan_unitObject

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



193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/tins/unit.rb', line 193

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