Class: Runby::Distance
- Inherits:
-
Object
- Object
- Runby::Distance
- Includes:
- Comparable
- Defined in:
- lib/runby_pace/distance.rb
Overview
Represents a distance (distance UOM and multiplier)
Instance Attribute Summary collapse
-
#multiplier ⇒ Object
readonly
Returns the value of attribute multiplier.
-
#uom ⇒ Object
readonly
Returns the value of attribute uom.
Class Method Summary collapse
Instance Method Summary collapse
- #*(other) ⇒ Distance
- #+(other) ⇒ Distance
- #-(other) ⇒ Distance
- #/(other) ⇒ Distance, Numeric
- #<=>(other) ⇒ Object
- #convert_to(target_uom) ⇒ Object
-
#initialize(uom = :km, multiplier = 1) ⇒ Distance
constructor
A new instance of Distance.
- #kilometers ⇒ Object
- #meters ⇒ Object
- #to_s(format: :short) ⇒ Object
Constructor Details
#initialize(uom = :km, multiplier = 1) ⇒ Distance
Returns a new instance of Distance.
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/runby_pace/distance.rb', line 16 def initialize(uom = :km, multiplier = 1) case uom when DistanceUnit init_from_distance_unit uom, multiplier when Symbol init_from_symbol uom, multiplier else raise 'Invalid distance unit of measure' end freeze end |
Instance Attribute Details
#multiplier ⇒ Object (readonly)
Returns the value of attribute multiplier.
8 9 10 |
# File 'lib/runby_pace/distance.rb', line 8 def multiplier @multiplier end |
#uom ⇒ Object (readonly)
Returns the value of attribute uom.
8 9 10 |
# File 'lib/runby_pace/distance.rb', line 8 def uom @uom end |
Class Method Details
.new(uom = :km, multiplier = 1) ⇒ Object
10 11 12 13 14 |
# File 'lib/runby_pace/distance.rb', line 10 def self.new(uom = :km, multiplier = 1) return uom if uom.is_a? Distance return Distance.parse uom if uom.is_a? String super end |
.parse(str) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/runby_pace/distance.rb', line 43 def self.parse(str) str = str.strip.chomp.downcase multiplier = str.scan(/[\d,.]+/).first multiplier = multiplier.nil? ? 1 : multiplier.to_f uom = str.scan(/[-_a-z ]+$/).first raise "Unable to find distance unit in '#{str}'" if uom.nil? parsed_uom = Runby::DistanceUnit.parse uom raise "'#{uom.strip}' is not recognized as a distance unit" if parsed_uom.nil? new parsed_uom, multiplier end |
.try_parse(str) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'lib/runby_pace/distance.rb', line 56 def self.try_parse(str) distance, = nil begin distance = parse str rescue StandardError => ex = ex..to_s end { distance: distance, error: } end |
Instance Method Details
#*(other) ⇒ Distance
103 104 105 106 107 |
# File 'lib/runby_pace/distance.rb', line 103 def *(other) raise "Cannot multiply Runby::Distance by #{other.class}" unless other.is_a?(Numeric) product_in_km = Distance.new(:km, kilometers * other) product_in_km.convert_to(@uom) end |
#+(other) ⇒ Distance
87 88 89 90 91 |
# File 'lib/runby_pace/distance.rb', line 87 def +(other) raise "Cannot add Runby::Distance to #{other.class}" unless other.is_a?(Distance) sum_in_km = Distance.new(:km, kilometers + other.kilometers) sum_in_km.convert_to(@uom) end |
#-(other) ⇒ Distance
95 96 97 98 99 |
# File 'lib/runby_pace/distance.rb', line 95 def -(other) raise "Cannot add Runby::Distance to #{other.class}" unless other.is_a?(Distance) sum_in_km = Distance.new(:km, kilometers - other.kilometers) sum_in_km.convert_to(@uom) end |
#/(other) ⇒ Distance, Numeric
111 112 113 114 115 116 117 118 119 |
# File 'lib/runby_pace/distance.rb', line 111 def /(other) raise "Cannot divide Runby::Distance by #{other.class}" unless other.is_a?(Numeric) || other.is_a?(Distance) if other.is_a?(Numeric) quotient_in_km = Distance.new(:km, kilometers / other) return quotient_in_km.convert_to(@uom) elsif other.is_a?(Distance) return kilometers / other.kilometers end end |
#<=>(other) ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/runby_pace/distance.rb', line 76 def <=>(other) raise "Unable to compare Runby::Distance to #{other.class}(#{other})" unless [Distance, String].include? other.class if other.is_a?(String) return 0 if to_s == other || to_s(format: :long) == other return self <=> Distance.try_parse(other)[:distance] end kilometers <=> other.kilometers end |
#convert_to(target_uom) ⇒ Object
28 29 30 31 32 33 |
# File 'lib/runby_pace/distance.rb', line 28 def convert_to(target_uom) target_uom = DistanceUnit.new target_uom unless target_uom.is_a?(DistanceUnit) return self if @uom == target_uom target_multiplier = kilometers / (target_uom.conversion_factor * 1.0) Distance.new target_uom, target_multiplier end |
#kilometers ⇒ Object
39 40 41 |
# File 'lib/runby_pace/distance.rb', line 39 def kilometers @multiplier * @uom.conversion_factor end |
#meters ⇒ Object
35 36 37 |
# File 'lib/runby_pace/distance.rb', line 35 def meters kilometers * 1000.0 end |
#to_s(format: :short) ⇒ Object
66 67 68 69 70 71 72 73 |
# File 'lib/runby_pace/distance.rb', line 66 def to_s(format: :short) formatted_multiplier = format('%g', @multiplier.round(2)) case format when :short then "#{formatted_multiplier} #{@uom.to_s(format: format)}" when :long then "#{formatted_multiplier} #{@uom.to_s(format: format, pluralize: (@multiplier > 1))}" else raise "Invalid string format #{format}" end end |