Class: Runby::DistanceUnit

Inherits:
Object
  • Object
show all
Defined in:
lib/runby_pace/distance_unit.rb

Overview

Represents the distance units (e.g. kilometers, miles) used in paces

including the human-readable description of each unit
and the factor used to convert it to kilometers.

Constant Summary collapse

UOM_DEFINITIONS =
{ km: { description: 'kilometer', description_plural: 'kilometers', conversion_factor: 1.0,
              synonyms: %w[k km kms kilometer kilometers] },
        m:  { description: 'meter', description_plural: 'meters', conversion_factor: 0.001,
              synonyms: %w[m meter meters] },
        mi: { description: 'mile', description_plural: 'miles', conversion_factor: 1.609344,
              synonyms: %w[mi mile miles] },
        ft: { description: 'foot', description_plural: 'feet', conversion_factor: 0.0003048,
              synonyms: %w[ft foot feet] },
        yd: { description: 'yard', description_plural: 'yards', conversion_factor: 1093.61,
              synonyms: %w[y yd yds yard yards] },
        # Fun distance unit of measures
        marathon: { description: 'marathon', description_plural: 'marathons', conversion_factor: 42.1648128,
synonyms: %w[marathon] } }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(unit_of_measure) ⇒ DistanceUnit

Returns a new instance of DistanceUnit.



16
17
18
19
20
21
22
# File 'lib/runby_pace/distance_unit.rb', line 16

def initialize(unit_of_measure)
  raise "':#{unit_of_measure}' is an unknown unit of measure" unless DistanceUnit.known_uom? unit_of_measure
  @symbol = unit_of_measure
  @conversion_factor = UOM_DEFINITIONS[@symbol][:conversion_factor]
  @description = UOM_DEFINITIONS[@symbol][:description]
  freeze
end

Instance Attribute Details

#conversion_factorObject (readonly)

Returns the value of attribute conversion_factor.



8
9
10
# File 'lib/runby_pace/distance_unit.rb', line 8

def conversion_factor
  @conversion_factor
end

#descriptionObject (readonly)

Returns the value of attribute description.



8
9
10
# File 'lib/runby_pace/distance_unit.rb', line 8

def description
  @description
end

#symbolObject (readonly)

Returns the value of attribute symbol.



8
9
10
# File 'lib/runby_pace/distance_unit.rb', line 8

def symbol
  @symbol
end

Class Method Details

.known_uom?(symbol) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/runby_pace/distance_unit.rb', line 60

def self.known_uom?(symbol)
  UOM_DEFINITIONS.key?(symbol)
end

.new(unit_of_measure) ⇒ Object



10
11
12
13
14
# File 'lib/runby_pace/distance_unit.rb', line 10

def self.new(unit_of_measure)
  return unit_of_measure if unit_of_measure.is_a? DistanceUnit
  return DistanceUnit.parse(unit_of_measure) if unit_of_measure.is_a? String
  super
end

.parse(description) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/runby_pace/distance_unit.rb', line 36

def self.parse(description)
  return new description if description.is_a? Symbol
  description = description.strip.chomp.downcase
  found_uom = nil
  UOM_DEFINITIONS.each do |uom, details|
    if details[:synonyms].include? description
      found_uom = uom
      break
    end
  end
  raise "Error parsing distance unit '#{description}'" unless found_uom
  DistanceUnit.new found_uom
end

.try_parse(str) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/runby_pace/distance_unit.rb', line 50

def self.try_parse(str)
  uom, error_message = nil
  begin
    uom = parse str
  rescue StandardError => ex
    error_message = ex.message
  end
  { uom: uom, error: error_message }
end

Instance Method Details

#==(other) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/runby_pace/distance_unit.rb', line 64

def ==(other)
  if other.is_a? DistanceUnit
    @symbol == other.symbol
  elsif other.is_a? String
    self == DistanceUnit.parse(other)
  else
    raise "Unable to compare DistanceUnit to #{other.class}(#{other})"
  end
end

#description_pluralObject



32
33
34
# File 'lib/runby_pace/distance_unit.rb', line 32

def description_plural
  UOM_DEFINITIONS[@symbol][:description_plural]
end

#to_s(format: :long, pluralize: false) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/runby_pace/distance_unit.rb', line 24

def to_s(format: :long, pluralize: false)
  case format
  when :short then @symbol.to_s
  when :long then pluralize ? description_plural : @description
  else raise "Invalid string format #{format}"
  end
end