Class: Quantity
- Inherits:
-
Object
- Object
- Quantity
- Includes:
- Comparable
- Defined in:
- lib/quantity.rb,
lib/quantity/unit.rb,
lib/quantity/version.rb,
lib/quantity/dimension.rb,
lib/quantity/systems/si.rb,
lib/quantity/dimension/base.rb,
lib/quantity/systems/enumerable.rb,
lib/quantity/systems/information.rb
Overview
a few countable quantities
Defined Under Namespace
Modules: VERSION Classes: Dimension, Unit
Instance Attribute Summary collapse
-
#reference_value ⇒ Object
readonly
This quantity in terms of the reference value, declared by fiat for everything measurable.
-
#unit ⇒ Object
readonly
Unit of measurement.
-
#value ⇒ Object
readonly
User-visible value, i.e.
Instance Method Summary collapse
-
#%(other) ⇒ Quantity
(also: #modulo)
Mod.
-
#*(other) ⇒ Quantity
Multiplication.
-
#**(power) ⇒ Quantity
Exponentiation.
-
#+(other) ⇒ Quantity
Addition.
-
#+@ ⇒ Quantity
Unary + (self).
-
#-(other) ⇒ Quantity
Subtraction.
-
#-@ ⇒ Quantity
Negation.
-
#/(other) ⇒ Quantity
Division.
-
#<=>(other) ⇒ -1 0 1
Comparison.
-
#abs ⇒ Quantity
Abs implementation.
-
#ceil ⇒ Quantity
Smallest integer quantity greater than or equal to this.
-
#coerce(other) ⇒ Quantity
Ruby coercion.
-
#convert(to) ⇒ Object
Convert to another unit of measurement.
-
#cubed ⇒ Quantity
Cube the units of this quantity.
-
#divmod(other) ⇒ Quantity
Divmod.
-
#eql?(other) ⇒ Boolean
Type-aware equality.
-
#floor ⇒ Quantity
Largest integer quantity less than or equal to this.
-
#initialize(value, unit = nil) ⇒ Quantity
constructor
Initialize a new, immutable quantity.
-
#inspect ⇒ String
Developer-friendly string representation.
-
#measures ⇒ Symbol String
What this measures.
- #respond_to?(method) ⇒ Boolean
-
#round ⇒ Quantity
Round this value to the nearest integer.
-
#squared ⇒ Quantity
Square the units of this quantity.
-
#to_f ⇒ Float
Float representation.
-
#to_i ⇒ Fixnum
Integer representation.
-
#to_s ⇒ String
String version of this quantity.
-
#truncate ⇒ Quantity
Truncate this value to an integer.
-
#units ⇒ Symbol String
Units of measurement.
-
#zero? ⇒ Boolean
Returns true if self has a zero value.
Constructor Details
#initialize(value, unit, options) ⇒ Quantity #initialize(options) ⇒ Quantity
Initialize a new, immutable quantity
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/quantity.rb', line 69 def initialize(value, unit = nil ) case value when Hash @unit = Unit.for(value[:unit]) @reference_value = value[:reference_value] || (value[:value] * @unit.value) @value = @unit.value_for(@reference_value) #dimension.reference.convert_proc(@unit).call(@reference_value) #@value = @unit.convert_proc(@unit).call(@reference_value) when Numeric @unit = Unit.for(unit) if @unit.nil? @unit = Unit.from_string_form(unit) end @value = value @reference_value = value * @unit.value end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
this creates the conversion methods of .to_* and .in_*
351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/quantity.rb', line 351 def method_missing(method, *args, &block) if method.to_s =~ /(to_|in_)(.*)/ if (Unit.is_unit?($2.to_sym)) convert($2.to_sym) else raise ArgumentError, "Unknown target unit type: #{$2}" end else raise NoMethodError, "Undefined method `#{method}` for #{self}:#{self.class}" end end |
Instance Attribute Details
#reference_value ⇒ Object (readonly)
This quantity in terms of the reference value, declared by fiat for everything measurable
51 52 53 |
# File 'lib/quantity.rb', line 51 def reference_value @reference_value end |
#unit ⇒ Object (readonly)
Unit of measurement
48 49 50 |
# File 'lib/quantity.rb', line 48 def unit @unit end |
#value ⇒ Object (readonly)
User-visible value, i.e. 2.meters.value == 2
45 46 47 |
# File 'lib/quantity.rb', line 45 def value @value end |
Instance Method Details
#%(other) ⇒ Quantity Also known as: modulo
Mod
245 246 247 248 249 250 251 252 253 |
# File 'lib/quantity.rb', line 245 def %(other) if (other.is_a?(Numeric)) Quantity.new(@value % other, @unit) elsif(other.is_a?(Quantity) && self.measures == other.measures) Quantity.new({:unit => @unit, :reference_value => @reference_value % other.reference_value}) else raise ArgumentError, "Cannot modulo #{other} with #{self}" end end |
#*(other) ⇒ Quantity
Multiplication.
181 182 183 184 185 186 187 188 189 |
# File 'lib/quantity.rb', line 181 def *(other) if (other.is_a?(Numeric)) Quantity.new(@value * other, @unit) elsif(other.is_a?(Quantity)) Quantity.new({:unit => other.unit * @unit, :reference_value => @reference_value * other.reference_value}) else raise ArgumentError, "Cannot multiply #{other} with #{self}" end end |
#**(power) ⇒ Quantity
Exponentiation. Quantities cannot be raised to negative or fractional powers, only positive Fixnum.
216 217 218 219 220 221 222 223 224 225 |
# File 'lib/quantity.rb', line 216 def **(power) unless power.is_a?(Fixnum) && power > 0 raise ArgumentError, "Quantities can only be raised to fixed powers (given #{power})" end if power == 1 self else self * self**(power - 1) end end |
#+(other) ⇒ Quantity
Addition. Add two quantities of the same type. Do not need to have the same units.
133 134 135 136 137 138 139 140 141 |
# File 'lib/quantity.rb', line 133 def +(other) if (other.is_a?(Numeric)) Quantity.new(@value + other, @unit) elsif(other.is_a?(Quantity) && @unit.dimension == other.unit.dimension) Quantity.new({:unit => @unit,:reference_value => @reference_value + other.reference_value}) else raise ArgumentError,"Cannot add #{self} to #{other}" end end |
#-(other) ⇒ Quantity
Subtraction. Subtract a quantity from another of the same type. They do not need to share units.
147 148 149 150 151 152 153 154 155 |
# File 'lib/quantity.rb', line 147 def -(other) if (other.is_a?(Numeric)) Quantity.new(@value - other, @unit) elsif(other.is_a?(Quantity) && @unit.dimension == other.unit.dimension) Quantity.new({:unit => @unit,:reference_value => @reference_value - other.reference_value}) else raise ArgumentError, "Cannot subtract #{other} from #{self}" end end |
#-@ ⇒ Quantity
Negation
260 261 262 |
# File 'lib/quantity.rb', line 260 def -@ Quantity.new({:unit => @unit, :reference_value => @reference_value * -1}) end |
#/(other) ⇒ Quantity
Division
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/quantity.rb', line 194 def /(other) if (other.is_a?(Numeric)) Quantity.new(@value / other, @unit) elsif(other.is_a?(Quantity)) ref = nil if defined?(Rational) && (@value.is_a?(Fixnum)) && (other.is_a?(Fixnum)) ref = Rational(@reference_value,other.reference_value) elsif defined?(Rational) && (@value.is_a?(Rational)) && (other.is_a?(Rational)) ref = @reference_value / other.reference_value else ref = @reference_value / other.reference_value.to_f end Quantity.new({:unit => @unit / other.unit, :reference_value => ref}) else raise ArgumentError, "Cannot multiply #{other} with #{self}" end end |
#<=>(other) ⇒ -1 0 1
Comparison. Compare this to another quantity or numeric. Compared to a numeric, this will assume a numeric of the same unit as self.
161 162 163 164 165 166 167 168 169 |
# File 'lib/quantity.rb', line 161 def <=>(other) if (other.is_a?(Numeric)) @value <=> other elsif(other.is_a?(Quantity) && measures == other.measures) @reference_value <=> other.reference_value else nil end end |
#abs ⇒ Quantity
Abs implementation
107 108 109 110 111 112 113 |
# File 'lib/quantity.rb', line 107 def abs if @reference_value < 0 -self else self end end |
#ceil ⇒ Quantity
Smallest integer quantity greater than or equal to this
302 303 304 |
# File 'lib/quantity.rb', line 302 def ceil Quantity.new(@value.ceil, @unit) end |
#coerce(other) ⇒ Quantity
Ruby coercion. Allows things like 2 + 5.meters
117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/quantity.rb', line 117 def coerce(other) if other.class == @value.class [Quantity.new(other, @unit),self] elsif defined?(Rational) && (@value.is_a?(Fixnum)) && (other.is_a?(Fixnum)) [Quantity.new(Rational(other), @unit), self] elsif defined?(Rational) && (other.is_a?(Rational)) [Quantity.new(other, @unit), self] else [Quantity.new(other.to_f, @unit),Quantity.new(@value.to_f, @unit)] end end |
#convert(to) ⇒ Object
Convert to another unit of measurement.
For most uses, Quantity#to_
330 331 332 |
# File 'lib/quantity.rb', line 330 def convert(to) Quantity.new({:unit => @unit.convert(to), :reference_value => @reference_value}) end |
#cubed ⇒ Quantity
Cube the units of this quantity
239 240 241 |
# File 'lib/quantity.rb', line 239 def cubed Quantity.new(@value, @unit * @unit * @unit) end |
#divmod(other) ⇒ Quantity
Divmod
308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/quantity.rb', line 308 def divmod(other) if (other.is_a?(Numeric)) (q, r) = @value.divmod(other) [Quantity.new(q,@unit),Quantity.new(r,@unit)] elsif (other.is_a?(Quantity) && measures == other.measures) (q, r) = @value.divmod(other.value) [Quantity.new(q,@unit),Quantity.new(r,@unit)] else raise ArgumentError, "Cannot divmod #{other} with #{self}" end end |
#eql?(other) ⇒ Boolean
Type-aware equality
174 175 176 |
# File 'lib/quantity.rb', line 174 def eql?(other) other.is_a?(Quantity) && other.units == units && self == other end |
#floor ⇒ Quantity
Largest integer quantity less than or equal to this
296 297 298 |
# File 'lib/quantity.rb', line 296 def floor Quantity.new(@value.floor, @unit) end |
#inspect ⇒ String
Developer-friendly string representation
345 346 347 |
# File 'lib/quantity.rb', line 345 def inspect to_s end |
#measures ⇒ Symbol String
What this measures
95 96 97 |
# File 'lib/quantity.rb', line 95 def measures @unit.dimension end |
#respond_to?(method) ⇒ Boolean
363 364 365 366 367 368 369 370 371 |
# File 'lib/quantity.rb', line 363 def respond_to?(method) if method.to_s =~ /(to_|in_)(.*)/ if (Unit.is_unit?($2.to_sym)) return true end end super end |
#round ⇒ Quantity
Round this value to the nearest integer
284 285 286 |
# File 'lib/quantity.rb', line 284 def round Quantity.new(@value.round, @unit) end |
#squared ⇒ Quantity
Square the units of this quantity
231 232 233 |
# File 'lib/quantity.rb', line 231 def squared Quantity.new(@value, @unit * @unit) end |
#to_f ⇒ Float
Float representation
278 279 280 |
# File 'lib/quantity.rb', line 278 def to_f @value.to_f end |
#to_i ⇒ Fixnum
Integer representation
272 273 274 |
# File 'lib/quantity.rb', line 272 def to_i @value.to_i end |
#to_s ⇒ String
String version of this quantity
89 90 91 |
# File 'lib/quantity.rb', line 89 def to_s @unit.s_for(value) end |
#truncate ⇒ Quantity
Truncate this value to an integer
290 291 292 |
# File 'lib/quantity.rb', line 290 def truncate Quantity.new(@value.truncate, @unit) end |
#units ⇒ Symbol String
Units of measurement
101 102 103 |
# File 'lib/quantity.rb', line 101 def units @unit.name end |
#zero? ⇒ Boolean
Returns true if self has a zero value
322 323 324 |
# File 'lib/quantity.rb', line 322 def zero? @value.zero? end |