Module: TrickBag::Numeric::KmgtNumericString

Defined in:
lib/trick_bag/numeric/kmgt_numeric_string.rb

Overview

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.

Defined Under Namespace

Classes: ToNumberConverter

Constant Summary collapse

MULTIPLIERS =
{
    'k' => 1_000,
    'K' => 1_024,
    'm' => 1_000 ** 2,
    'M' => 1_024 ** 2,
    'g' => 1_000 ** 3,
    'G' => 1_024 ** 3,
    't' => 1_000 ** 4,
    'T' => 1_024 ** 4,
}
VALID_STRING_SUFFIXES =
MULTIPLIERS.keys
VALID_STRING_REGEX =

only digits with optional minus sign prefix

/^-?\d+/

Class Method Summary collapse

Class Method Details

.range_string?(string) ⇒ Boolean

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

Returns:

  • (Boolean)


40
41
42
43
44
# 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) ⇒ Object

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.



34
35
36
# 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) ⇒ Object

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.



61
62
63
64
65
66
67
68
69
70
# 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) ⇒ Object

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.



49
50
51
52
53
54
55
56
# 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