module TrickBag::Numeric::KmgtNumericString

Converts number strings with optional suffixes of [kKmMgGtT] to integers. Upper case letters represent powers of 1024, and lower case letters represent powers of 1000 (see MULTIPLIERS below).

Also supports ranges, e.g. '1k..5k' will be converted by to_range to (1000..5000).

Methods are to_number, to_range, and to_number_or_range. See tests for usage examples.

Constants

MULTIPLIERS
VALID_STRING_REGEX
VALID_STRING_SUFFIXES

Public Instance Methods

range_string?(string) click to toggle source

Returns whether or not this is a number range string. Specifically, tests that the string contains only 2 numeric strings separated by '..'.

# File lib/trick_bag/numeric/kmgt_numeric_string.rb, line 40
def range_string?(string)
  return false unless string.is_a?(String)
  number_strings = string.split('..')
  number_strings.size == 2 && number_strings.all? { |str| VALID_STRING_REGEX.match(str) }
end
to_number(object) click to toggle source

Converts a numeric string (e.g. '3', '2k') to a number. If the passed parameter is not a string, it is returned unchanged. This eliminates the need for the caller to do their own type test.

# File lib/trick_bag/numeric/kmgt_numeric_string.rb, line 34
def to_number(object)
  object.is_a?(String) ? ToNumberConverter.new(object).to_number : object
end
to_number_or_range(object) click to toggle source

Converts a string such as '3' or '1k..2k' into a number or range. If nil or an Integer or Range is passed, it is returned unchanged. This eliminates the need for the caller to do their own type test.

# File lib/trick_bag/numeric/kmgt_numeric_string.rb, line 61
def to_number_or_range(object)
  case object
    when Integer, Range, NilClass
      object
    when String
      range_string?(object) ? to_range(object) : to_number(object)
    else
      raise ArgumentError.new("Invalid argument, class is #{object.class}, object is (#{object}).")
    end
end
to_range(object) click to toggle source

Converts the passed string to a range (see range_string? above for the string's format). If the passed parameter is nil or is a Range already, returns it unchanged. This eliminates the need for the caller to do their own type test.

# File lib/trick_bag/numeric/kmgt_numeric_string.rb, line 49
def to_range(object)
  return object if object.is_a?(Range) || object.nil?
  unless range_string?(object)
      raise ArgumentError.new("Invalid argument (#{object}); Range must be 2 numbers separated by '..', e.g. 10..20 or 900K..1M")
  end
  numbers = object.split('..').map { |s| to_number(s) }
  (numbers.first..numbers.last)
end