class Unitwise::Unit
A Unit
is essentially a collection of Unitwise::Term
. Terms can be combined through multiplication or division to create a unit. A unit does not have a magnitude, but it does have a scale.
Public Class Methods
Create a new unit. You can send an expression or a collection of terms @param input [String, Unit
, [Term]] A string expression, a unit, or a collection of tems. @api public
# File lib/unitwise/unit.rb, line 13 def initialize(input) case input when Compatible @expression = input.expression when String, Symbol @expression = input.to_s else @terms = input end end
Public Instance Methods
Multiply this unit by another unit, term, or number. @param other [Unitwise::Unit, Unitwise::Term
, Numeric] @return [Unitwise::Unit] @api public
# File lib/unitwise/unit.rb, line 110 def *(other) operate('*', other) || fail(TypeError, "Can't multiply #{ self } by #{ other }.") end
Raise this unit to a numeric power. @param other [Numeric] @return [Unitwise::Unit] @api public
# File lib/unitwise/unit.rb, line 129 def **(other) if other.is_a?(Numeric) self.class.new(terms.map { |t| t ** other }) else fail TypeError, "Can't raise #{self} to #{other}." end end
Divide this unit by another unit,term, or number. @param other [Unitwise::Unit, Unitwise::Term
, Numeric] @return [Unitwise::Unit] @api public
# File lib/unitwise/unit.rb, line 119 def /(other) operate('/', other) || fail(TypeError, "Can't divide #{ self } by #{ other }.") end
A collection of the possible string representations of this unit. Primarily used by Unitwise::Search
. @return [Array] @api public
# File lib/unitwise/unit.rb, line 150 def aliases [:names, :primary_code, :secondary_code, :symbol].map do |mode| to_s(mode) end.uniq end
The collection of atoms that compose this unit. Essentially delegated to terms. @return [Array] @api public
# File lib/unitwise/unit.rb, line 56 def atoms terms.map(&:atom) end
A number representing this unit's distance from it's deepest terminal atom. @return [Integer] @api public
# File lib/unitwise/unit.rb, line 72 def depth terms.map(&:depth).max + 1 end
Build a string representation of this unit by it's terms. @param mode [Symbol] The mode to use to stringify the atoms (:primary_code, :names, :secondary_code). @return [String] @api public
# File lib/unitwise/unit.rb, line 44 def expression(mode=nil) if @expression && (mode.nil? || mode == self.mode) @expression else Expression.compose(terms, mode || self.mode) end end
Get a magnitude for this unit based on a linear scale value. Should only be used by units with special atoms in it's hierarchy. @param scalar [Numeric] A linear scalar value @return [Numeric] The equivalent magnitude on this scale @api public
# File lib/unitwise/unit.rb, line 100 def magnitude(scalar = scalar()) terms.reduce(1) do |prod, term| prod * term.magnitude(scalar) end end
The default mode to use for inspecting and printing. @return [Symbol] @api semipublic
# File lib/unitwise/unit.rb, line 160 def mode terms @mode || :primary_code end
A collection of the deepest terms, or essential composition of the unit. @return [Array] @api public
# File lib/unitwise/unit.rb, line 80 def root_terms terms.map(&:root_terms).flatten end
Get a scalar value for this unit. @param magnitude [Numeric] An optional magnitude on this unit's scale. @return [Numeric] A scalar value on a linear scale @api public
# File lib/unitwise/unit.rb, line 89 def scalar(magnitude = 1) terms.reduce(1) do |prod, term| prod * term.scalar(magnitude) end end
Is this unit special (meaning on a non-linear scale)? @return [true, false] @api public
# File lib/unitwise/unit.rb, line 64 def special? terms.count == 1 && terms.all?(&:special?) end
The collection of terms used by this unit. @return [Array] @api public
# File lib/unitwise/unit.rb, line 27 def terms unless frozen? unless @terms decomposer = Expression.decompose(@expression) @mode = decomposer.mode @terms = decomposer.terms end freeze end @terms end
A string representation of this unit. @param mode [:symbol] The mode used to represent the unit (:primary_code, :names, :secondary_code) @return [String] @api public
# File lib/unitwise/unit.rb, line 142 def to_s(mode = nil) expression(mode) end
Private Instance Methods
Multiply or divide units @api private
# File lib/unitwise/unit.rb, line 169 def operate(operator, other) exp = operator == '/' ? -1 : 1 if other.respond_to?(:terms) self.class.new(terms + other.terms.map { |t| t ** exp }) elsif other.respond_to?(:atom) self.class.new(terms << other ** exp) elsif other.is_a?(Numeric) self.class.new(terms.map { |t| t.send(operator, other) }) end end