Class: Measurement
- Inherits:
-
Object
- Object
- Measurement
- Defined in:
- lib/ruby-measurement/unit.rb,
lib/ruby-measurement/version.rb,
lib/ruby-measurement/measurement.rb
Defined Under Namespace
Classes: Unit
Constant Summary collapse
- VERSION =
'1.0.0'
- UNIT_REGEX =
/([a-zA-Z].*)/.freeze
- SCIENTIFIC_NUMBER =
/([+-]?\d*\.?\d+(?:[Ee][+-]?)?\d*)/.freeze
- SCIENTIFIC_REGEX =
/\A#{SCIENTIFIC_NUMBER}\s*#{UNIT_REGEX}?\z/.freeze
- RATIONAL_REGEX =
/\A([+-]?\d+\s+)?((\d+)\/(\d+))?\s*#{UNIT_REGEX}?\z/.freeze
- COMPLEX_REGEX =
/\A#{SCIENTIFIC_NUMBER}?#{SCIENTIFIC_NUMBER}i\s*#{UNIT_REGEX}?\z/.freeze
Class Attribute Summary collapse
-
.units ⇒ Object
Returns the value of attribute units.
Instance Attribute Summary collapse
-
#quantity ⇒ Object
readonly
Returns the value of attribute quantity.
-
#unit ⇒ Object
readonly
Returns the value of attribute unit.
Class Method Summary collapse
Instance Method Summary collapse
- #*(obj) ⇒ Object
- #**(obj) ⇒ Object
- #+(obj) ⇒ Object
- #-(obj) ⇒ Object
- #/(obj) ⇒ Object
- #==(obj) ⇒ Object
- #convert_to(unit_name) ⇒ Object
- #convert_to!(unit_name) ⇒ Object
-
#initialize(quantity, unit_name = :count) ⇒ Measurement
constructor
A new instance of Measurement.
- #inspect ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(quantity, unit_name = :count) ⇒ Measurement
Returns a new instance of Measurement.
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/ruby-measurement/measurement.rb', line 16 def initialize(quantity, unit_name = :count) unit = unit_name unit = self.class.units[unit_name.to_s] if unit_name.kind_of?(Symbol) || unit_name.kind_of?(String) raise ArgumentError, "Invalid quantity: #{quantity}" unless quantity.kind_of?(Numeric) raise ArgumentError, "Invalid unit: #{unit_name}" unless unit.kind_of?(Unit) @quantity = quantity @unit = unit end |
Class Attribute Details
.units ⇒ Object
Returns the value of attribute units.
13 14 15 |
# File 'lib/ruby-measurement/measurement.rb', line 13 def units @units end |
Instance Attribute Details
#quantity ⇒ Object (readonly)
Returns the value of attribute quantity.
11 12 13 |
# File 'lib/ruby-measurement/measurement.rb', line 11 def quantity @quantity end |
#unit ⇒ Object (readonly)
Returns the value of attribute unit.
11 12 13 |
# File 'lib/ruby-measurement/measurement.rb', line 11 def unit @unit end |
Class Method Details
.define(unit_name, &block) ⇒ Object
161 162 163 164 |
# File 'lib/ruby-measurement/measurement.rb', line 161 def self.define(unit_name, &block) unit = Unit.new(unit_name, &block) unit.aliases.each { |a| @units[a.downcase] = unit } end |
.parse(str = '0') ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/ruby-measurement/measurement.rb', line 131 def self.parse(str = '0') str = str.strip if str =~ COMPLEX_REGEX real, imaginary, unit_name = str.scan(COMPLEX_REGEX).first quantity = Complex(real.to_f, imaginary.to_f).to_f elsif str =~ SCIENTIFIC_REGEX whole, unit_name = str.scan(SCIENTIFIC_REGEX).first quantity = whole.to_f elsif str =~ RATIONAL_REGEX whole, _, numerator, denominator, unit_name = str.scan(RATIONAL_REGEX).first if numerator && denominator numerator = numerator.to_f + (denominator.to_f * whole.to_f) denominator = denominator.to_f quantity = Rational(numerator, denominator).to_f else quantity = whole.to_f end else raise ArgumentError, "Unable to parse: '#{str}'" end unit_name ||= 'count' unit = units[unit_name.strip.downcase] raise ArgumentError, "Invalid unit: '#{unit_name}'" unless unit new(quantity, unit) end |
.unit(unit_name) ⇒ Object
126 127 128 129 |
# File 'lib/ruby-measurement/measurement.rb', line 126 def self.unit(unit_name) unit_name = unit_name.to_s @units.values.find { |unit| unit.aliases.include?(unit_name) } end |
Instance Method Details
#*(obj) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/ruby-measurement/measurement.rb', line 65 def *(obj) case obj when Numeric self.class.new(quantity * obj.to_f, unit) when self.class if obj.unit == unit self.class.new(quantity * obj.quantity, unit) else self * obj.convert_to(unit) end else raise ArgumentError, "Invalid arithmetic: #{self} * #{obj}" end end |
#**(obj) ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/ruby-measurement/measurement.rb', line 95 def **(obj) case obj when Numeric self.class.new(quantity ** obj.to_f, unit) else raise ArgumentError, "Invalid arithmetic: #{self} ** #{obj}" end end |
#+(obj) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/ruby-measurement/measurement.rb', line 35 def +(obj) case obj when Numeric self.class.new(quantity + obj.to_f, unit) when self.class if obj.unit == unit self.class.new(quantity + obj.quantity, unit) else self + obj.convert_to(unit) end else raise ArgumentError, "Invalid arithmetic: #{self} + #{obj}" end end |
#-(obj) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ruby-measurement/measurement.rb', line 50 def -(obj) case obj when Numeric self.class.new(quantity - obj.to_f, unit) when self.class if obj.unit == unit self.class.new(quantity - obj.quantity, unit) else self - obj.convert_to(unit) end else raise ArgumentError, "Invalid arithmetic: #{self} - #{obj}" end end |
#/(obj) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ruby-measurement/measurement.rb', line 80 def /(obj) case obj when Numeric self.class.new(quantity / obj.to_f, unit) when self.class if obj.unit == unit self.class.new(quantity / obj.quantity, unit) else self / obj.convert_to(unit) end else raise ArgumentError, "Invalid arithmetic: #{self} / #{obj}" end end |
#==(obj) ⇒ Object
104 105 106 |
# File 'lib/ruby-measurement/measurement.rb', line 104 def ==(obj) obj.kind_of?(self.class) && quantity == obj.quantity && unit == obj.unit end |
#convert_to(unit_name) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ruby-measurement/measurement.rb', line 108 def convert_to(unit_name) unit = self.class.unit(unit_name) raise ArgumentError, "Invalid unit: '#{unit_name}'" unless unit return dup if unit == @unit conversion = @unit.conversion(unit.name) raise ArgumentError, "Invalid conversion: '#@unit' to '#{unit.name}'" unless conversion self.class.new(conversion.call(@quantity), unit.name) end |
#convert_to!(unit_name) ⇒ Object
120 121 122 123 124 |
# File 'lib/ruby-measurement/measurement.rb', line 120 def convert_to!(unit_name) measurement = convert_to(unit_name) @unit, @quantity = measurement.unit, measurement.quantity self end |
#inspect ⇒ Object
27 28 29 |
# File 'lib/ruby-measurement/measurement.rb', line 27 def inspect to_s end |
#to_s ⇒ Object
31 32 33 |
# File 'lib/ruby-measurement/measurement.rb', line 31 def to_s "#{quantity} #{unit}" end |