Class: Unit

Inherits:
Numeric show all
Defined in:
lib/unit/dsl.rb,
lib/unit/class.rb,
lib/unit/system.rb,
lib/unit/version.rb

Defined Under Namespace

Classes: System

Constant Summary collapse

VERSION =
'0.3.0'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value, unit, system) ⇒ Unit

Returns a new instance of Unit.



5
6
7
8
9
10
11
# File 'lib/unit/class.rb', line 5

def initialize(value, unit, system)
  @system = system
  @value = value
  @unit = unit.dup
  @normalized = nil
  reduce!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name) ⇒ Object



16
17
18
19
20
21
22
# File 'lib/unit/dsl.rb', line 16

def method_missing(name)
  if name.to_s =~ /^in_/
    self.in(Unit.method_name_to_unit($'))
  else
    Unit.to_unit(Unit.method_name_to_unit(name), system) * self
  end
end

Class Attribute Details

.default_systemObject

Returns the value of attribute default_system.



231
232
233
# File 'lib/unit/class.rb', line 231

def default_system
  @default_system
end

Instance Attribute Details

#normalizedObject (readonly)

Returns the value of attribute normalized.



3
4
5
# File 'lib/unit/class.rb', line 3

def normalized
  @normalized
end

#systemObject (readonly)

Returns the value of attribute system.



3
4
5
# File 'lib/unit/class.rb', line 3

def system
  @system
end

#unitObject (readonly)

Returns the value of attribute unit.



3
4
5
# File 'lib/unit/class.rb', line 3

def unit
  @unit
end

#valueObject (readonly)

Returns the value of attribute value.



3
4
5
# File 'lib/unit/class.rb', line 3

def value
  @value
end

Class Method Details

.method_name_to_unit(name) ⇒ Object



12
13
14
# File 'lib/unit/dsl.rb', line 12

def self.method_name_to_unit(name)
  name.to_s.sub(/^per_/, '1/').gsub('_per_', '/').gsub('_', ' ')
end

.to_unit(object, system = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/unit/class.rb', line 140

def self.to_unit(object, system = nil)
  system ||= Unit.default_system
  case object
  when Unit
    raise TypeError, 'Different unit system' if object.system != system
    object
  when Array
    system.validate_unit(object)
    Unit.new(1, object, system)
  when String, Symbol
    unit = system.parse_unit(object.to_s)
    system.validate_unit(unit)
    Unit.new(1, unit, system)
  when Numeric
    Unit.new(object, [], system)
  else
    raise TypeError, "#{object.class} has no unit support"
  end
end

Instance Method Details

#*(other) ⇒ Object



46
47
48
49
# File 'lib/unit/class.rb', line 46

def *(other)
  a, b = coerce(other)
  Unit.new(a.value * b.value, a.unit + b.unit, system)
end

#**(exp) ⇒ Object

Raises:

  • (TypeError)


64
65
66
67
# File 'lib/unit/class.rb', line 64

def **(exp)
  raise TypeError if Unit === exp
  Unit.new(value ** exp, Unit.power_unit(unit, exp), system)
end

#+(other) ⇒ Object

Raises:

  • (TypeError)


57
58
59
60
61
62
# File 'lib/unit/class.rb', line 57

def +(other)
  raise TypeError, "Incompatible units: #{self.inspect} and #{other.inspect}" if !compatible?(other)
  a, b = coerce(other)
  a, b = a.normalize, b.normalize
  Unit.new(a.value + b.value, a.unit, system).in(self)
end

#-(other) ⇒ Object



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

def -(other)
  self + (-other)
end

#-@Object



73
74
75
# File 'lib/unit/class.rb', line 73

def -@
  Unit.new(-value, unit, system)
end

#/(other) ⇒ Object



51
52
53
54
55
# File 'lib/unit/class.rb', line 51

def /(other)
  a, b = coerce(other)
  Unit.new(Integer === a.value && Integer === b.value ? Rational(a.value, b.value) : a.value / b.value,
           a.unit + Unit.power_unit(b.unit, -1), system)
end

#<=>(other) ⇒ Object



83
84
85
86
87
# File 'lib/unit/class.rb', line 83

def <=>(other)
  a, b = coerce(other)
  a, b = a.normalize, b.normalize
  a.value <=> b.value if a.unit == b.unit
end

#==(other) ⇒ Object



77
78
79
80
81
# File 'lib/unit/class.rb', line 77

def ==(other)
  a, b = coerce(other)
  a, b = a.normalize, b.normalize
  a.value == b.value && a.unit == b.unit
end

#approxObject



132
133
134
# File 'lib/unit/class.rb', line 132

def approx
  to_f.unit(unit)
end

#coerce(val) ⇒ Object



136
137
138
# File 'lib/unit/class.rb', line 136

def coerce(val)
  [self, Unit.to_unit(val, system)]
end

#compatible?(other) ⇒ Boolean Also known as: compatible_with?

Compatible units can be added

Returns:

  • (Boolean)


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

def compatible?(other)
  a, b = coerce(other)
  a, b = a.normalize, b.normalize
  a.unit == b.unit
end

#dimensionless?Boolean Also known as: unitless?

Number without dimension

Returns:

  • (Boolean)


90
91
92
# File 'lib/unit/class.rb', line 90

def dimensionless?
  normalize.unit.empty?
end

#in(unit) ⇒ Object

Convert to other unit



106
107
108
109
110
# File 'lib/unit/class.rb', line 106

def in(unit)
  a, b = coerce(unit)
  conversion = Unit.new(1, b.unit, system)
  (a / conversion).normalize * conversion
end

#initialize_copy(other) ⇒ Object



13
14
15
16
17
18
# File 'lib/unit/class.rb', line 13

def initialize_copy(other)
  @system = other.system
  @value = other.value
  @unit = other.unit.dup
  @normalized = other.normalized
end

#inspectObject



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

def inspect
  unit.empty? ? %{Unit("#{value}")} : %{Unit("#{value} #{unit_string('.')}")}
end

#normalizeObject

Converts to base units



21
22
23
# File 'lib/unit/class.rb', line 21

def normalize
  @normalized ||= dup.normalize!
end

#normalize!Object

Converts to base units



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/unit/class.rb', line 26

def normalize!
  if @normalized != self
    begin
      last_unit = @unit
      @unit = []
      last_unit.each do |factor, unit, exp|
        @value *= @system.factor[factor][:value] ** exp if factor != :one
        if Numeric === unit
          @unit << [:one, unit, exp]
        else
          @unit += Unit.power_unit(@system.unit[unit][:def], exp)
        end
      end
    end while last_unit != @unit
    reduce!
    @normalized = self
  end
  self
end

#to_fObject



128
129
130
# File 'lib/unit/class.rb', line 128

def to_f
  @value.to_f
end

#to_iObject



124
125
126
# File 'lib/unit/class.rb', line 124

def to_i
  @value.to_i
end

#to_sObject



116
117
118
# File 'lib/unit/class.rb', line 116

def to_s
  unit.empty? ? value.to_s : "#{value} #{unit_string('ยท')}"
end

#to_texObject



120
121
122
# File 'lib/unit/class.rb', line 120

def to_tex
  unit.empty? ? value.to_s : "\SI{#{value}}{#{unit_string('.')}}"
end