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

new(input) click to toggle source

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

*(other) click to toggle source

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
**(other) click to toggle source

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
/(other) click to toggle source

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
aliases() click to toggle source

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
atoms() click to toggle source

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
depth() click to toggle source

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
expression(mode=nil) click to toggle source

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
magnitude(scalar = scalar()) click to toggle source

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
mode() click to toggle source

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
root_terms() click to toggle source

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
scalar(magnitude = 1) click to toggle source

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
special?() click to toggle source

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
terms() click to toggle source

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
to_s(mode = nil) click to toggle source

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

operate(operator, other) click to toggle source

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