class Reality::Measure::Unit
Constants
- OP_REGEX
- POWER_REGEX
- UNICODE_SUPER
- UNIT_REGEX
Attributes
unicode[RW]
components[R]
Public Class Methods
new(*components)
click to toggle source
# File lib/reality/measure/unit.rb, line 53 def initialize(*components) @components = components. group_by{|sig, pow| sig}. map{|sig, cmps| [sig, cmps.map(&:last).inject(:+)]}. reject{|sig, pow| pow.zero?} end
parse(str)
click to toggle source
# File lib/reality/measure/unit.rb, line 15 def parse(str) return str if str.kind_of?(Unit) scanner = StringScanner.new(str) denom = false units = [] loop do # (variable [power] operator) .... unit = scanner.scan(UNIT_REGEX) or fail("Variable expected at #{scanner.rest}") pow = scanner.scan(POWER_REGEX) units << [unit, parse_pow(pow, denom)] break if scanner.eos? op = scanner.scan(OP_REGEX) or fail("Operator expected at #{scanner.rest}") if op == '/' denom and fail("Second division at #{scanner.rest}") denom = true end end new(*units) end
parse_pow(p, denom)
click to toggle source
# File lib/reality/measure/unit.rb, line 38 def parse_pow(p, denom) res = case p when nil then 1 when '²' then 2 when '³' then 3 when /^\^(\d+)$/ then $1.to_i else fail(ArgumentError, "Can't parse power #{p}") end denom ? -res : res end
Public Instance Methods
*(other)
click to toggle source
# File lib/reality/measure/unit.rb, line 72 def *(other) other.class == self.class or fail(TypeError, "Can't multiply #{self.class} by #{other.class}") self.class.new(*components, *other.components) end
-@()
click to toggle source
# File lib/reality/measure/unit.rb, line 68 def -@ self.class.new(*components.map{|sig, pow| [sig, -pow]}) end
/(other)
click to toggle source
# File lib/reality/measure/unit.rb, line 79 def /(other) other.class == self.class or fail(TypeError, "Can't divide #{self.class} by #{other.class}") self * -other end
==(other)
click to toggle source
# File lib/reality/measure/unit.rb, line 60 def ==(other) other.class == self.class && other.components == self.components end
inspect()
click to toggle source
# File lib/reality/measure/unit.rb, line 100 def inspect "#<#{self.class}(#{to_s})>" end
scalar?()
click to toggle source
# File lib/reality/measure/unit.rb, line 64 def scalar? components.empty? end
to_s()
click to toggle source
# File lib/reality/measure/unit.rb, line 86 def to_s num, denom = components.partition{|sig, pow| pow > 0} numerator = num.map{|sig, pow| "#{sig}#{power(pow)}"}.join(mul) denominator = denom.map{|sig, pow| "#{sig}#{power(pow)}"}.join(mul) case when numerator.empty? [1, denominator].join('/') when denominator.empty? numerator else [numerator, denominator].join('/') end end
Private Instance Methods
mul()
click to toggle source
# File lib/reality/measure/unit.rb, line 108 def mul self.class.unicode ? '·' : '*' end
power(num)
click to toggle source
# File lib/reality/measure/unit.rb, line 112 def power(num) num = num.abs case num when 0 then fail(ArgumentError, "0-power unit!") when 1 then '' when 2..3 self.class.unicode ? UNICODE_SUPER.fetch(num) : "^#{num}" else "^#{num}" end end