class NumericWithUnit::Unit
Attributes
derivation[R]
dimension[R]
symbol[R]
Instance Methods
Public Class Methods
<<(arg)
click to toggle source
add unit to base unit list.
# File lib/numeric_with_unit/unit.rb, line 192 def self.<<(arg) if arg.is_a?(self) @@list << arg else @@list << Unit[arg] end end
[](arg)
click to toggle source
apply to_s
to arg and return parsed unit.
# File lib/numeric_with_unit/unit.rb, line 170 def self.[](arg) self.parse(arg.to_s) end
[]=(key, arg)
click to toggle source
cast unit and add unit to base unit list at the same time.
# File lib/numeric_with_unit/unit.rb, line 175 def self.[]=(key, arg) if arg.is_a?(Array) and arg.size == 2 a = [key, arg.first] u = arg.last else a = [key] u = arg end @@list << (u.is_a?(self) ? u : self[u]).cast(*a) end
assign() { |config| ... }
click to toggle source
create new unit and add unit to base unit list at the same time.
# File lib/numeric_with_unit/unit.rb, line 206 def self.assign @@list << self.new{|config| yield(config)} end
delete(unit_symbol)
click to toggle source
remove unit from base unit list.
# File lib/numeric_with_unit/unit.rb, line 201 def self.delete(unit_symbol) @@list.delete_if{|unit| unit.symbol == unit_symbol} end
derive() { |derivation| ... }
click to toggle source
create new unit from derivation _(for internal use)_ .
# File lib/numeric_with_unit/unit.rb, line 109 def self.derive #(block) derivation = Hash.new(0) yield(derivation) derivation.delete_if{|k,v| k.symbol.nil?} return Unit.new if derivation.empty? # constructing symbol h = derivation.reject{|k,v| k.symbol.empty?}.sort_by{|u,v| u.symbol}.sort_by{|u,v| v} syms_pos = h.select{|u,v| v > 0}.map{|u,v| u.symbol + (v.abs>1 ? v.abs.to_s : '')} syms_neg = h.select{|u,v| v < 0}.map{|u,v| u.symbol + (v.abs>1 ? v.abs.to_s : '')} symbol = syms_pos.join('.') symbol += '/' + (syms_neg.size>1 ? "(#{syms_neg.join('.')})" : "#{syms_neg.first}") unless syms_neg.empty? # constructing dimension dimension = Hash.new(0) derivation.each do |u,v| u.dimension.each do |d,i| dimension[d] += i*v end end # constructing from_si proc from_si = derivation.map{|u,v| prc = if v > 0 ->(x){u.from_si(x)} else ->(x){x.quo(u.from_si(1)-u.from_si(0))} #FIXME: ℃とKの変換のような場合に、変換式の切片を消すため。変換式が線形じゃないケースは想定していない end [prc, v.abs] }.map{|prc,v| ->(x){ v.times{x = prc[x]}; x } }.reduce{|memo, prc| ->(x){memo[prc[x]]} } # constructing to_si proc to_si = derivation.map{|u,v| prc = if v > 0 ->(x){u.to_si(x)} else ->(x){x.quo(u.to_si(1)-u.to_si(0))} #FIXME: ℃とKの変換のような場合に、変換式の切片を消すため。変換式が線形じゃないケースは想定していない end [prc, v.abs] }.map{|prc,v| ->(x){ v.times{x = prc[x]}; x } }.reduce{|memo, prc| ->(x){memo[prc[x]]} } # deriving new unit self.new(derivation){|config| config.symbol = symbol config.dimension = dimension config.from_si = from_si config.to_si = to_si } end
list()
click to toggle source
return base unit list.
# File lib/numeric_with_unit/unit.rb, line 187 def self.list @@list end
new(derivation=nil) { |config| ... }
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 330 def initialize(derivation=nil) # TODO: Unit::Configとinitializeの役割が分離できていないので見なおせ config = Config.new yield(config) if block_given? config.compile @symbol = config.symbol @dimension = config.dimension @from_si = config.from_si @to_si = config.to_si unless derivation derivation = Hash.new(0) derivation[self] += 1 end @derivation = derivation end
parse(unit_str)
click to toggle source
parsing unit_str (ex. “kg”, km/hr“, ”cm2“) to (derived) unit.
# File lib/numeric_with_unit/unit.rb, line 212 def self.parse(unit_str) rec = ->(arg){__send__(__method__, arg)} dervation_str = parse_3rd(parse_2nd(parse_1st(unit_str))) derive{|derivation| dervation_str.each do |unit_str, order| if i = @@list.rindex{|unit| unit.symbol == unit_str} derivation[@@list[i]] += order elsif m = unit_str.match(/^(?<prefix>#{@@prefix.keys.join('|')})(?<unit>#{list.join('|')})$/) and m[:unit].empty?.! u = rec[m[:unit]].cast(unit_str, @@prefix[m[:prefix]]) derivation[u] += order else raise NoUnitError, "[#{unit_str}] is not defined!" end end } end
Public Instance Methods
*(other_unit)
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 395 def *(other_unit) self.class.derive do |derivation| @derivation.each{|k, v| derivation[k] += v} other_unit.derivation.each{|k, v| derivation[k] += v} end end
**(num)
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 409 def **(num) if num.zero? self.class.new else self.class.derive do |derivation| # NOTE: # ここto_iでOKか?v*numが整数じゃなければraiseすべき?→すべき→NumericWithUnitでやるべき? # Unitでは整数じゃない次数の単位は許容すべきか否か→していい気がする @derivation.each{|k, v| derivation[k] = (v*num).to_i} end end end
/(other_unit)
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 402 def /(other_unit) self.class.derive do |derivation| @derivation.each{|k, v| derivation[k] += v} other_unit.derivation.each{|k, v| derivation[k] -= v} end end
==(other)
click to toggle source
Calls superclass method
# File lib/numeric_with_unit/unit.rb, line 387 def ==(other) if other.is_a?(self.class) symbol == other.symbol and dimension == other.dimension else super end end
cast(new_symbol, factor = 1)
click to toggle source
create new unit with new symbol and factor from self. use for converting [in] = 25.4 .
# File lib/numeric_with_unit/unit.rb, line 350 def cast(new_symbol, factor = 1) self.class.new do |config| config.symbol = new_symbol config.dimension = @dimension config.from_si = ->(x){from_si(x.quo(factor))} config.to_si = ->(x){to_si(x * factor)} end end
dimension_equal?(other_unit)
click to toggle source
return true if self and other_unit have the same dimension.
# File lib/numeric_with_unit/unit.rb, line 381 def dimension_equal?(other_unit) (@dimension.keys | other_unit.dimension.keys).all?{|k| @dimension[k] == other_unit.dimension[k] } end
dimensionless?()
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 376 def dimensionless? @dimension.all?{|k,v| v.zero?} end
from_si(value)
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 371 def from_si(value) @from_si.call(value) end
inspect()
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 363 def inspect "#<#{self.class}:[#{@symbol}] #{@dimension}>" end
simplify()
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 423 def simplify self.class.derive{|derivation| @dimension.each do|d,o| u = self.class.list.find{|u| u.dimension == {d => 1}} #TODO: find? ok? raise NoUnitError, "No unit with #{{d=>1}} dimension is assined." unless u derivation[u] = o end } end
to_s()
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 359 def to_s @symbol end
to_si(value)
click to toggle source
# File lib/numeric_with_unit/unit.rb, line 367 def to_si(value) @to_si.call(value) end