Class: Unitwise::Unit

Inherits:
Object
  • Object
show all
Includes:
Compatible
Defined in:
lib/unitwise/unit.rb

Overview

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.

Instance Method Summary collapse

Methods included from Compatible

#<=>, #compatible_with?, #composition, #composition_string, #dim, included

Constructor Details

#initialize(input) ⇒ Unit

Create a new unit. You can send an expression or a collection of terms collection of tems.

Parameters:

  • input (String, Unit, [Term])

    A string expression, a unit, or a



13
14
15
16
17
18
19
20
21
22
# 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

Instance Method Details

#*(other) ⇒ Unitwise::Unit

Multiply this unit by another unit, term, or number.

Parameters:

Returns:



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/unitwise/unit.rb', line 107

def *(other)
  if other.respond_to?(:terms)
    self.class.new(terms + other.terms)
  elsif other.respond_to?(:atom)
    self.class.new(terms << other)
  elsif other.is_a?(Numeric)
    self.class.new(terms.map { |t| t * other })
  else
    fail TypeError, "Can't multiply #{self} by #{other}."
  end
end

#**(other) ⇒ Unitwise::Unit

Raise this unit to a numeric power.

Parameters:

Returns:



139
140
141
142
143
144
145
# File 'lib/unitwise/unit.rb', line 139

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) ⇒ Unitwise::Unit

Divide this unit by another unit,term, or number.

Parameters:

Returns:



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/unitwise/unit.rb', line 123

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

#aliasesArray

A collection of the possible string representations of this unit. Primarily used by Unitwise::Search.

Returns:

  • (Array)


160
161
162
163
164
# File 'lib/unitwise/unit.rb', line 160

def aliases
  [:names, :primary_code, :secondary_code, :symbol].map do |mode|
    to_s(mode)
  end.uniq
end

#atomsArray

The collection of atoms that compose this unit. Essentially delegated to terms.

Returns:

  • (Array)


53
54
55
# File 'lib/unitwise/unit.rb', line 53

def atoms
  terms.map(&:atom)
end

#depthInteger

A number representing this unit’s distance from it’s deepest terminal atom.

Returns:

  • (Integer)


69
70
71
# File 'lib/unitwise/unit.rb', line 69

def depth
  terms.map(&:depth).max + 1
end

#expression(mode = mode) ⇒ String

Build a string representation of this unit by it’s terms. (:primary_code, :names, :secondary_code).

Parameters:

  • mode (Symbol) (defaults to: mode)

    The mode to use to stringify the atoms

Returns:

  • (String)


44
45
46
# File 'lib/unitwise/unit.rb', line 44

def expression(mode = mode)
  Expression.compose(terms, mode)
end

#magnitude(scalar = scalar) ⇒ Numeric

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.

Parameters:

  • scalar (Numeric) (defaults to: scalar)

    A linear scalar value

Returns:

  • (Numeric)

    The equivalent magnitude on this scale



97
98
99
100
101
# File 'lib/unitwise/unit.rb', line 97

def magnitude(scalar = scalar)
  terms.reduce(1.0) do |prod, term|
    prod * term.magnitude(scalar)
  end
end

#modeSymbol

The default mode to use for inspecting and printing.

Returns:

  • (Symbol)


170
171
172
173
# File 'lib/unitwise/unit.rb', line 170

def mode
  terms
  @mode || :primary_code
end

#root_termsArray

A collection of the deepest terms, or essential composition of the unit.

Returns:

  • (Array)


77
78
79
# File 'lib/unitwise/unit.rb', line 77

def root_terms
  terms.map(&:root_terms).flatten
end

#scalar(magnitude = 1.0) ⇒ Numeric

Get a scalar value for this unit.

Parameters:

  • magnitude (Numeric) (defaults to: 1.0)

    An optional magnitude on this unit’s scale.

Returns:

  • (Numeric)

    A scalar value on a linear scale



86
87
88
89
90
# File 'lib/unitwise/unit.rb', line 86

def scalar(magnitude = 1.0)
  terms.reduce(1.0) do |prod, term|
    prod * term.scalar(magnitude)
  end
end

#special?true, false

Is this unit special (meaning on a non-linear scale)?

Returns:

  • (true, false)


61
62
63
# File 'lib/unitwise/unit.rb', line 61

def special?
  terms.count == 1 && terms.all?(&:special?)
end

#termsArray

The collection of terms used by this unit.

Returns:

  • (Array)


27
28
29
30
31
32
33
34
35
36
37
# File 'lib/unitwise/unit.rb', line 27

def terms
  unless frozen?
    unless @terms
      decomposer = Expression::Decomposer.new(@expression)
      @mode  = decomposer.mode
      @terms = decomposer.terms
    end
    freeze
  end
  @terms
end

#to_s(mode = mode) ⇒ String

A string representation of this unit. (:primary_code, :names, :secondary_code)

Parameters:

  • mode (:symbol) (defaults to: mode)

    The mode used to represent the unit

Returns:

  • (String)


152
153
154
# File 'lib/unitwise/unit.rb', line 152

def to_s(mode = mode)
  expression(mode || self.mode)
end