class Runby::Distance
Represents a distance (distance UOM and multiplier)
Attributes
multiplier[R]
uom[R]
Public Class Methods
new(uom = :km, multiplier = 1)
click to toggle source
Calls superclass method
# 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
new(uom = :km, multiplier = 1)
click to toggle source
# 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
parse(str)
click to toggle source
# 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)
click to toggle source
# File lib/runby_pace/distance.rb, line 56 def self.try_parse(str) distance, error_message = nil begin distance = parse str rescue StandardError => ex error_message = ex.message.to_s end { distance: distance, error: error_message } end
Public Instance Methods
*(other)
click to toggle source
@param [Numeric] other @return [Distance]
# 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)
click to toggle source
@param [Distance] other @return [Distance]
# 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)
click to toggle source
@param [Distance] other @return [Distance]
# 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)
click to toggle source
@param [Numeric, Distance] other @return [Distance, Numeric]
# 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)
click to toggle source
@param [Distance, String] other
# 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)
click to toggle source
# 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()
click to toggle source
# File lib/runby_pace/distance.rb, line 39 def kilometers @multiplier * @uom.conversion_factor end
meters()
click to toggle source
# File lib/runby_pace/distance.rb, line 35 def meters kilometers * 1000.0 end
to_s(format: :short)
click to toggle source
# 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
Private Instance Methods
init_from_distance_unit(uom, multiplier)
click to toggle source
# File lib/runby_pace/distance.rb, line 123 def init_from_distance_unit(uom, multiplier) @uom = uom @multiplier = multiplier end
init_from_symbol(distance_uom_symbol, multiplier)
click to toggle source
# File lib/runby_pace/distance.rb, line 128 def init_from_symbol(distance_uom_symbol, multiplier) raise "Unknown unit of measure #{distance_uom_symbol}" unless Runby::DistanceUnit.known_uom? distance_uom_symbol raise 'Invalid multiplier' unless multiplier.is_a?(Numeric) @uom = DistanceUnit.new distance_uom_symbol @multiplier = multiplier * 1.0 end