Class: Unitwise::Measurement

Inherits:
Scale
  • Object
show all
Defined in:
lib/unitwise/measurement.rb

Overview

A Measurement is a combination of a numeric value and a unit. You can think of this as a type of vector where the direction is the unit designation and the value is the magnitude. This is the primary class that outside code will interact with. Comes with conversion, comparison, and math methods.

Instance Method Summary collapse

Methods inherited from Scale

#atoms, #depth, #eql?, #expression, #hash, #inspect, #magnitude, #root_terms, #scalar, #simplified_value, #special?, #terms, #to_s, #unit=

Methods included from Compatible

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

Constructor Details

#initialize(*args) ⇒ Measurement

Create a new Measurement Measurement::Unit

Examples:

Unitwise::Measurement.new(20, 'm/s')


14
15
16
17
# File 'lib/unitwise/measurement.rb', line 14

def initialize(*args)
  super(*args)
  terms
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object

Will attempt to convert to a unit by method name.

Examples:

measurement.to_foot # => <Unitwise::Measurement 4 foot>


139
140
141
142
143
144
145
146
147
148
149
# File 'lib/unitwise/measurement.rb', line 139

def method_missing(meth, *args, &block)
  if args.empty? && !block_given? && (match = /\Ato_(\w+)\Z/.match(meth.to_s))
    begin
      convert_to(match[1])
    rescue ExpressionError
      super(meth, *args, &block)
    end
  else
    super(meth, *args, &block)
  end
end

Instance Method Details

#*(other) ⇒ Object

Multiply this measurement by a number or another measurement

Examples:

measurent * 5
measurement * some_other_measurement


41
42
43
44
# File 'lib/unitwise/measurement.rb', line 41

def *(other)
  operate(:*, other) ||
    fail(TypeError, "Can't multiply #{self} by #{other}.")
end

#**(other) ⇒ Object

Raise a measurement to a numeric power.

Examples:

measurement ** 2


80
81
82
83
84
85
86
# File 'lib/unitwise/measurement.rb', line 80

def **(other)
  if other.is_a?(Numeric)
    new(value ** other, unit ** other)
  else
    fail TypeError, "Can't raise #{self} to #{other} power."
  end
end

#+(other) ⇒ Object

Add another measurement to this unit. Units must be compatible.

Examples:

measurement + some_other_measurement


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

def +(other)
  combine(:+, other) || fail(TypeError, "Can't add #{other} to #{self}.")
end

#-(other) ⇒ Object

Subtract another measurement from this unit. Units must be compatible.

Examples:

measurement - some_other_measurement


70
71
72
73
# File 'lib/unitwise/measurement.rb', line 70

def -(other)
  combine(:-, other) ||
    fail(TypeError, "Can't subtract #{other} from #{self}.")
end

#/(other) ⇒ Object

Divide this measurement by a number or another measurement

Examples:

measurement / 2
measurement / some_other_measurement


52
53
54
# File 'lib/unitwise/measurement.rb', line 52

def /(other)
  operate(:/, other) || fail(TypeError, "Can't divide #{self} by #{other}")
end

#coerce(other) ⇒ Object

Coerce a numeric to a a measurement for mathematical operations

Examples:

2.5 * measurement
4 / measurement


102
103
104
105
106
107
108
109
# File 'lib/unitwise/measurement.rb', line 102

def coerce(other)
  case other
  when Numeric
    return self.class.new(other, '1'), self
  else
    fail TypeError, "#{self.class} can't be coerced into #{other.class}"
  end
end

#convert_to(other_unit) ⇒ Object

Convert this measurement to a compatible unit. or a Measurement::Unit

Examples:

measurement1.convert_to('foot')
measurement2.convert_to('kilogram')


26
27
28
29
30
31
32
33
# File 'lib/unitwise/measurement.rb', line 26

def convert_to(other_unit)
  other_unit = Unit.new(other_unit)
  if compatible_with?(other_unit)
    new(converted_value(other_unit), other_unit)
  else
    fail ConversionError, "Can't convert #{self} to #{other_unit}."
  end
end

#round(digits = nil) ⇒ Integer, Float

Round the measurement value. Delegates to the value's class.



91
92
93
94
# File 'lib/unitwise/measurement.rb', line 91

def round(digits = nil)
  rounded_value = digits ? value.round(digits) : value.round
  self.class.new(rounded_value, unit)
end

#to_fObject

Convert a measurement to a Float.

Examples:

measurement.to_f # => 4.25


123
124
125
# File 'lib/unitwise/measurement.rb', line 123

def to_f
  Float(value)
end

#to_iObject

Convert a measurement to an Integer.

Examples:

measurement.to_i # => 4


115
116
117
# File 'lib/unitwise/measurement.rb', line 115

def to_i
  Integer(value)
end

#to_rObject

Convert a measurement to a Rational.

Examples:

measurement.to_r # => (17/4)


131
132
133
# File 'lib/unitwise/measurement.rb', line 131

def to_r
  Rational(value)
end