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.3'
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
RATIOS =
{
  '¼' => '1/4',
  '½' => '1/2',
  '¾' => '3/4',
  '⅓' => '1/3',
  '⅔' => '2/3',
  '⅕' => '1/5',
  '⅖' => '2/5',
  '⅗' => '3/5',
  '⅘' => '4/5',
  '⅙' => '1/6',
  '⅚' => '5/6',
  '⅛' => '1/8',
  '⅜' => '3/8',
  '⅝' => '5/8',
  '⅞' => '7/8',
}.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)


33
34
35
36
37
38
39
40
41
42
# File 'lib/ruby-measurement/measurement.rb', line 33

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.



31
32
33
# File 'lib/ruby-measurement/measurement.rb', line 31

def quantity
  @quantity
end

#unitObject (readonly)

Returns the value of attribute unit.



31
32
33
# File 'lib/ruby-measurement/measurement.rb', line 31

def unit
  @unit
end

Class Method Details

.define(unit_name, &block) ⇒ Object



120
121
122
# File 'lib/ruby-measurement/measurement.rb', line 120

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

.parse(str = '0') ⇒ Object

Raises:

  • (ArgumentError)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ruby-measurement/measurement.rb', line 103

def parse(str = '0')
  str = normalize(str)

  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



71
72
73
74
75
76
77
78
# File 'lib/ruby-measurement/measurement.rb', line 71

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



80
81
82
# File 'lib/ruby-measurement/measurement.rb', line 80

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

#convert_to(unit_name) ⇒ Object

Raises:

  • (ArgumentError)


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

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



96
97
98
99
100
# File 'lib/ruby-measurement/measurement.rb', line 96

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

#inspectObject



44
45
46
# File 'lib/ruby-measurement/measurement.rb', line 44

def inspect
  to_s
end

#to_sObject



48
49
50
# File 'lib/ruby-measurement/measurement.rb', line 48

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