class ReeNumber::NumberToHuman
def calculate_exponent(number, locale, units)
def calculate_exponent(number, locale, units) exponent = number != 0 ? Math.log10(number.abs).floor : 0 unit_exponents(units, locale).find { |e| exponent >= e } || 0 end
def call(number, **opts)
def call(number, **opts) options = DEFAULTS.merge(opts) number = round_helper( number, **slice(options, [:precision, :significant, :round_mode]) ) number = Float(number) exponent = calculate_exponent( number, options[:locale], options[:units] ) number = number / (10**exponent) rounded_number = number_to_rounded( number, **slice( options, [:precision, :significant, :strip_insignificant_zeros, :round_mode] ) ) unit = determine_unit( exponent, options[:units], options[:locale] ) result_number = options[:format] .gsub("%n", rounded_number) .gsub("%u", unit) .strip number_to_delimited( result_number, **slice(options, [:separator, :delimiter]) ) end
def determine_unit(exponent, units, locale)
def determine_unit(exponent, units, locale) exp = DECIMAL_UNITS[exponent] case units when Hash units[exp] || "" when String, Symbol t("human.#{units}.#{exp}", locale: locale, default_by_locale: :en) else t("human.decimal_units.#{exp}", count: number.to_i, default_by_locale: :en) end end
def unit_exponents(units, locale)
def unit_exponents(units, locale) case units when Hash units when String, Symbol t("human.#{units}", locale: locale, raise: true, default_by_locale: :en) else raise ArgumentError, ":units must be a Hash or String translation scope." end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by(&:-@) end