class Unitwise::Measurement
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.
Public Class Methods
Create a new Measurement
@param value [Numeric] The scalar value for the measurement @param unit [String, Measurement::Unit] Either a string expression, or a Measurement::Unit @example
Unitwise::Measurement.new(20, 'm/s')
@api public
# File lib/unitwise/measurement.rb, line 14 def initialize(*args) super(*args) terms end
Public Instance Methods
Multiply this measurement by a number or another measurement @param other [Numeric, Unitwise::Measurement] @example
measurent * 5 measurement * some_other_measurement
@api public
# File lib/unitwise/measurement.rb, line 41 def *(other) operate(:*, other) || fail(TypeError, "Can't multiply #{self} by #{other}.") end
Raise a measurement to a numeric power. @param number [Numeric] @example
measurement ** 2
@api public
# 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
Add another measurement to this unit. Units must be compatible. @param other [Unitwise::Measurement] @example
measurement + some_other_measurement
@api public
# File lib/unitwise/measurement.rb, line 61 def +(other) combine(:+, other) || fail(TypeError, "Can't add #{other} to #{self}.") end
Subtract another measurement from this unit. Units must be compatible. @param (see +
) @example
measurement - some_other_measurement
@api public
# File lib/unitwise/measurement.rb, line 70 def -(other) combine(:-, other) || fail(TypeError, "Can't subtract #{other} from #{self}.") end
Divide this measurement by a number or another measurement @param (see *
) @example
measurement / 2 measurement / some_other_measurement
@api public
# File lib/unitwise/measurement.rb, line 52 def /(other) operate(:/, other) || fail(TypeError, "Can't divide #{self} by #{other}") end
Coerce a numeric to a a measurement for mathematical operations @param other [Numeric] @example
2.5 * measurement 4 / measurement
@api public
# 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 this measurement to a compatible unit. @param other_unit [String, Measurement::Unit] Either a string expression or a Measurement::Unit @example
measurement1.convert_to('foot') measurement2.convert_to('kilogram')
@api public
# 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
Will attempt to convert to a unit by method name. @example
measurement.to_foot # => <Unitwise::Measurement 4 foot>
@api semipublic
# 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
Round the measurement value. Delegates to the value's class. @return [Integer, Float] @api public
# 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
Convert a measurement to a Float. @example
measurement.to_f # => 4.25
@api public
# File lib/unitwise/measurement.rb, line 123 def to_f Float(value) end
Convert a measurement to an Integer. @example
measurement.to_i # => 4
@api public
# File lib/unitwise/measurement.rb, line 115 def to_i Integer(value) end
Convert a measurement to a Rational. @example
measurement.to_r # => (17/4)
@api public
# File lib/unitwise/measurement.rb, line 131 def to_r Number.rationalize(value) end
Private Instance Methods
Add or subtract other unit @api private
# File lib/unitwise/measurement.rb, line 171 def combine(operator, other) if other.respond_to?(:composition) && compatible_with?(other) new(value.send(operator, other.convert_to(unit).value), unit) end end
Determine value of the unit after conversion to another unit @api private
# File lib/unitwise/measurement.rb, line 161 def converted_value(other_unit) if other_unit.special? other_unit.magnitude scalar else scalar / other_unit.scalar end end
Helper method to create a new instance from this instance @api private
# File lib/unitwise/measurement.rb, line 155 def new(*args) self.class.new(*args) end
Multiply or divide other unit @api private
# File lib/unitwise/measurement.rb, line 179 def operate(operator, other) if other.is_a?(Numeric) new(value.send(operator, other), unit) elsif other.respond_to?(:composition) if compatible_with?(other) converted = other.convert_to(unit) new(value.send(operator, converted.value), unit.send(operator, converted.unit)) else new(value.send(operator, other.value), unit.send(operator, other.unit)) end end end