Class: Measurement

Inherits:
Object
  • Object
show all
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.2.2'
UNIT_REGEX =
/([^\d\s\/].*)/.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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(quantity, unit_name = :count) ⇒ Measurement

Returns a new instance of Measurement.

Raises:

  • (ArgumentError)


13
14
15
16
17
18
19
20
21
22
# File 'lib/ruby-measurement/measurement.rb', line 13

def initialize(quantity, unit_name = :count)
  unit = unit_name
  unit = Unit[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

Instance Attribute Details

#quantityObject (readonly)

Returns the value of attribute quantity.



11
12
13
# File 'lib/ruby-measurement/measurement.rb', line 11

def quantity
  @quantity
end

#unitObject (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



99
100
101
# File 'lib/ruby-measurement/measurement.rb', line 99

def self.define(unit_name, &block)
  Unit.define(unit_name, &block)
end

.parse(str = '0') ⇒ Object

Raises:

  • (ArgumentError)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ruby-measurement/measurement.rb', line 82

def self.parse(str = '0')
  str = str.strip
  
  case str
    when COMPLEX_REGEX then unit_name, quantity = parse_complex(str)
    when SCIENTIFIC_REGEX then unit_name, quantity = parse_scientific(str)
    when RATIONAL_REGEX then unit_name, quantity = parse_rational(str)
    else raise ArgumentError, "Unable to parse: '#{str}'"
  end
  
  unit_name ||= 'count'
  unit = Unit[unit_name.strip.downcase]
  raise ArgumentError, "Invalid unit: '#{unit_name}'" unless unit
  
  new(quantity, unit)
end

Instance Method Details

#**(obj) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/ruby-measurement/measurement.rb', line 51

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



60
61
62
# File 'lib/ruby-measurement/measurement.rb', line 60

def ==(obj)
  obj.kind_of?(self.class) && quantity == obj.quantity && unit == obj.unit
end

#convert_to(unit_name) ⇒ Object

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ruby-measurement/measurement.rb', line 64

def convert_to(unit_name)
  unit = 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



76
77
78
79
80
# File 'lib/ruby-measurement/measurement.rb', line 76

def convert_to!(unit_name)
  measurement = convert_to(unit_name)
  @unit, @quantity = measurement.unit, measurement.quantity
  self
end

#inspectObject



24
25
26
# File 'lib/ruby-measurement/measurement.rb', line 24

def inspect
  to_s
end

#to_sObject



28
29
30
# File 'lib/ruby-measurement/measurement.rb', line 28

def to_s
  "#{quantity} #{unit}"
end