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