lib/unitwise/unit.rb in unitwise-0.10.0 vs lib/unitwise/unit.rb in unitwise-1.0.0
- old
+ new
@@ -7,10 +7,11 @@
include Compatible
# 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
def initialize(input)
case input
when Compatible
@expression = input.expression
when String, Symbol
@@ -18,10 +19,13 @@
else
@terms = input
end
end
+ # The collection of terms used by this unit.
+ # @return [Array]
+ # @api public
def terms
unless frozen?
unless @terms
decomposer = Expression::Decomposer.new(@expression)
@mode = decomposer.mode
@@ -30,46 +34,78 @@
freeze
end
@terms
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
def expression(mode = mode)
Expression.compose(terms, mode)
end
+
+ # The collection of atoms that compose this unit. Essentially delegated to
+ # terms.
+ # @return [Array]
+ # @api public
def atoms
terms.map(&:atom)
end
memoize :atoms
+ # Is this unit special (meaning on a non-linear scale)?
+ # @return [true, false]
+ # @api public
def special?
terms.count == 1 && terms.all?(&:special?)
end
memoize :special?
+ # A number representing this unit's distance from it's deepest terminal atom.
+ # @return [Integer]
+ # @api public
def depth
terms.map(&:depth).max + 1
end
memoize :depth
+ # A collection of the deepest terms, or essential composition of the unit.
+ # @return [Array]
+ # @api public
def root_terms
terms.map(&:root_terms).flatten
end
memoize :root_terms
+ # 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
def scalar(magnitude = 1.0)
terms.reduce(1.0) do |prod, term|
prod * term.scalar(magnitude)
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
def magnitude(scalar = scalar)
terms.reduce(1.0) do |prod, term|
prod * term.magnitude(scalar)
end
end
+ # Multiply this unit by another unit, term, or number.
+ # @param other [Unitwise::Unit, Unitwise::Term, Numeric]
+ # @return [Unitwise::Unit]
+ # @api public
def *(other)
if other.respond_to?(:terms)
self.class.new(terms + other.terms)
elsif other.respond_to?(:atom)
self.class.new(terms << other)
@@ -78,38 +114,60 @@
else
fail TypeError, "Can't multiply #{self} by #{other}."
end
end
+ # Divide this unit by another unit,term, or number.
+ # @param other [Unitwise::Unit, Unitwise::Term, Numeric]
+ # @return [Unitwise::Unit]
+ # @api public
def /(other)
if other.respond_to?(:terms)
self.class.new(terms + other.terms.map { |t| t ** -1 })
elsif other.respond_to?(:atom)
self.class.new(terms << other ** -1)
+ elsif other.is_a?(Numeric)
+ self.class.new(terms.map { |t| t / other })
else
fail TypeError, "Can't divide #{self} by #{other}."
end
end
+ # Raise this unit to a numeric power.
+ # @param other [Numeric]
+ # @return [Unitwise::Unit]
+ # @api public
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
+ # 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
def to_s(mode = mode)
expression(mode || self.mode)
end
+ # A collection of the possible string representations of this unit.
+ # Primarily used by Unitwise::Search.
+ # @return [Array]
+ # @api public
def aliases
- [:names, :primary_code, :secondary_code, :symbol].map do |mode|
+ [:names, :primary_code, :secondary_code, :symbol].map do |mode|
to_s(mode)
end.uniq
end
memoize :aliases
+ # The default mode to use for inspecting and printing.
+ # @return [Symbol]
+ # @api semipublic
def mode
terms
@mode || :primary_code
end