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



12
13
14
15
16
17
18
19
20
21
# File 'lib/unitwise/unit.rb', line 12

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) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/unitwise/unit.rb', line 71

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) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/unitwise/unit.rb', line 93

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) ⇒ Object



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

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)
  else
    fail TypeError, "Can't divide #{self} by #{other}."
  end
end

#aliasesObject



105
106
107
108
109
# File 'lib/unitwise/unit.rb', line 105

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

#atomsObject



39
40
41
# File 'lib/unitwise/unit.rb', line 39

def atoms
  terms.map(&:atom)
end

#depthObject



49
50
51
# File 'lib/unitwise/unit.rb', line 49

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

#expression(mode = mode) ⇒ Object



35
36
37
# File 'lib/unitwise/unit.rb', line 35

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

#magnitude(scalar = scalar) ⇒ Object



65
66
67
68
69
# File 'lib/unitwise/unit.rb', line 65

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

#modeObject



112
113
114
115
# File 'lib/unitwise/unit.rb', line 112

def mode
  terms
  @mode || :primary_code
end

#root_termsObject



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

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

#scalar(magnitude = 1.0) ⇒ Object



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

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

#special?Boolean

Returns:

  • (Boolean)


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

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

#termsObject



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/unitwise/unit.rb', line 23

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) ⇒ Object



101
102
103
# File 'lib/unitwise/unit.rb', line 101

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