class Numeric MILLI = 0.001 CENTI = MILLI * 10 DECI = CENTI * 10 DECA = 10 HECTO = DECA * 10 KILO = HECTO * 10 KILOBYTE = 1024 MEGABYTE = KILOBYTE * 1024 GIGABYTE = MEGABYTE * 1024 TERABYTE = GIGABYTE * 1024 PETABYTE = TERABYTE * 1024 EXABYTE = PETABYTE * 1024 FEET = 12 YARD = FEET * 3 MILE = YARD * 1760 NAUTICAL_MILE = MILE * 1.15078 METRIC_TON = KILO * 1000 POUND = 16 STONE = POUND * 14 TON = POUND * 2000 MINUTE = 60 HOUR = MINUTE * 60 DAY = HOUR * 24 WEEK = DAY * 7 YEAR = DAY * 365.25 DECADE = YEAR * 10 CENTURY = DECADE * 10 MILLENNIUM = CENTURY * 10 def add(n) self + n end unless method_defined?(:bytes) def bytes self end alias_method :byte, :bytes end def centigrams self * CENTI end alias_method :centigram, :centigrams def centimeters self * CENTI end alias_method :centimeter, :centimeters def centuries self * CENTURY end alias_method :century, :centuries def days self * DAY end alias_method :day, :days def decades self * DECADE end alias_method :decade, :decades def decagrams self * DECA end alias_method :decagram, :decagrams def decameters self * DECA end alias_method :decameter, :decameters def decigrams self * DECI end alias_method :decigram, :decigrams def decimeters self * DECI end alias_method :decimeter, :decimeters def divide(n) self / n end unless method_defined?(:exabytes) def exabytes self * EXABYTE end alias_method :exabyte, :exabytes end def feet self * FEET end alias_method :foot, :feet unless method_defined?(:gigabytes) def gigabytes self * GIGABYTE end alias_method :gigabyte, :gigabytes end def grams self end alias_method :gram, :grams def hectograms self * HECTO end alias_method :hectogram, :hectograms def hectometers self * HECTO end alias_method :hectometer, :hectometers def hours self * HOUR end alias_method :hour, :hours def inches self end alias_method :inch, :inches unless method_defined?(:kilobytes) def kilobytes self * KILOBYTE end alias_method :kilobyte, :kilobytes end def kilometers self * KILO end alias_method :kilometer, :kilometers def kilograms self * KILO end alias_method :kilogram, :kilograms def metric_tons self * METRIC_TON end alias_method :metric_ton, :metric_tons unless method_defined?(:megabytes) def megabytes self * MEGABYTE end alias_method :megabyte, :megabytes end def meters self end alias_method :meter, :meters def miles self * MILE end alias_method :mile, :miles def millenniums self * MILLENNIUM end alias_method :millennium, :millenniums def milligrams self * MILLI end alias_method :milligram, :milligrams def millimeters self * MILLI end alias_method :millimeter, :millimeters def minutes self * MINUTE end alias_method :minute, :minutes def multiply(n) self * n end unless method_defined?(:multiple_of?) def multiple_of?(number) number != 0 ? modulo(number).zero? : zero? end end def nautical_miles self * NAUTICAL_MILE end alias_method :nautical_mile, :nautical_miles def negative? self < 0 end unless method_defined?(:ordinal) def ordinal abs_number = abs if (11..13).include?(abs_number % 100) "th" else case abs_number % 10 when 1; "st" when 2; "nd" when 3; "rd" else "th" end end end end unless method_defined?(:ordinalize) def ordinalize "#{self}#{self.ordinal}" end end def ounces self end alias_method :ounce, :ounces def pad(options={}) pad_number = options.fetch(:pad_number, 0) precision = options.fetch(:precision, 3) to_s.rjust(precision, pad_number.to_s) end def pad_precision(options={}) pad_number = options.fetch(:pad_number, 0) precision = options.fetch(:precision, 2) separator = options.fetch(:separator, ".") string = to_s string << separator unless string.include?(separator) ljust_count = string.split(separator).first.size ljust_count += (string.count(separator) + precision) if precision > 0 num_count = string.size ljust_count >= num_count ? string.ljust(ljust_count, pad_number.to_s) : string[0..(ljust_count - 1)] end unless method_defined?(:petabytes) def petabytes self * PETABYTE end alias_method :petabyte, :petabytes end def positive? self > 0 end def pounds self * POUND end alias_method :pound, :pounds def power(n) self ** n end def root(n) self ** (1.0 / n) end def seconds self end alias_method :second, :seconds def stones self * STONE end alias_method :stone, :stones def subtract(n) self - n end unless method_defined?(:terabytes) def terabytes self * TERABYTE end alias_method :terabyte, :terabytes end def to_byte(from, to) valid_keys = [ :byte, :bytes, :kilobyte, :kilobytes, :megabyte, :megabytes, :gigabyte, :gigabytes, :terabyte, :terabytes, :petabyte, :petabytes, :exabyte, :exabytes ] unless valid_keys.include?(from) && valid_keys.include?(to) raise ArgumentError, "Unknown key(s): form: #{from.inspect} and to: #{to.inspect}, Valid keys are: #{valid_keys.map(&:inspect).join(', ')}" end to_f * 1.send(from) / 1.send(to) end def to_length(from, to) valid_keys = [ :meter, :meters, :millimeter, :millimeters, :centimeter, :centimeters, :decimeter, :decimeters, :decameter, :decameters, :hectometer, :hectometers, :kilometer, :kilometers, :inch, :inches, :foot, :feet, :yard, :yards, :mile, :miles, :nautical_mile, :nautical_miles ] unless valid_keys.include?(from) && valid_keys.include?(to) raise ArgumentError, "Unknown key(s): form: #{from.inspect} and to: #{to.inspect}, Valid keys are: #{valid_keys.map(&:inspect).join(', ')}" end case to when from self when :meter, :meters, :millimeter, :millimeters, :centimeter, :centimeters, :decimeter, :decimeters, :decameter, :decameters, :hectometer, :hectometers, :kilometer, :kilometers if valid_keys.first(14).include?(from) to_f * 1.send(from) / 1.send(to) else to_f * ((1.send(from) * 0.0254) / 1.send(to)) end when :inch, :inches, :foot, :feet, :yard, :yards, :mile, :miles, :nautical_mile, :nautical_miles if valid_keys.first(14).include?(from) to_f * ((1.send(from) * 39.3701) / 1.send(to)) else to_f * 1.send(from) / 1.send(to) end end end def to_mass(from, to) valid_keys = [ :gram, :grams, :milligram, :milligrams, :centigram, :centigrams, :decigram, :decigrams, :decagram, :decagrams, :hectogram, :hectograms, :kilogram, :kilograms, :metric_ton, :metric_tons, :ounce, :ounces, :pound, :pounds, :stone, :stones, :ton, :tons ] unless valid_keys.include?(from) && valid_keys.include?(to) raise ArgumentError, "Unknown key(s): form: #{from.inspect} and to: #{to.inspect}, Valid keys are: #{valid_keys.map(&:inspect).join(', ')}" end case to when from self when :gram, :grams, :milligram, :milligrams, :centigram, :centigrams, :decigram, :decigrams, :decagram, :decagrams, :hectogram, :hectograms, :kilogram, :kilograms, :metric_ton, :metric_tons if valid_keys.first(16).include?(from) to_f * 1.send(from) / 1.send(to) else to_f * ((1.send(from) * 28.3495) / 1.send(to)) end when :ounce, :ounces, :pound, :pounds, :stone, :stones, :ton, :tons if valid_keys.first(16).include?(from) to_f * ((1.send(from) * 0.035274) / 1.send(to)) else to_f * 1.send(from) / 1.send(to) end end end def to_nearest_value(values=[]) return(self) if values.size.zero? value = values.first difference = (self - value).abs values.each do |v| if (self - v).abs < difference difference = (self - v).abs value = v end end value end def to_temperature(from, to) valid_keys = [:celsius, :fahrenheit, :kelvin] unless valid_keys.include?(from) && valid_keys.include?(to) raise ArgumentError, "Unknown key(s): form: #{from.inspect} and to: #{to.inspect}, Valid keys are: #{valid_keys.map(&:inspect).join(', ')}" end case to when from self when :celsius from == :kelvin ? (to_f - 273.15) : ((to_f - 32.0) * 5.0 / 9.0) when :fahrenheit from == :kelvin ? (1.8 * (to_f - 273.15) + 32.0) : ((to_f * 9.0 / 5.0) + 32.0) when :kelvin from == :celsius ? (to_f + 273.15) : (((to_f - 32.0) * 5.0 / 9.0) + 273.15) end end def to_time(from, to) valid_keys = [ :second, :seconds, :minute, :minutes, :hour, :hours, :day, :days, :week, :weeks, :year, :years, :decade, :decades, :century, :centuries, :millennium, :millenniums ] unless valid_keys.include?(from) && valid_keys.include?(to) raise ArgumentError, "Unknown key(s): form: #{from.inspect} and to: #{to.inspect}, Valid keys are: #{valid_keys.map(&:inspect).join(', ')}" end to_f * 1.send(from) / 1.send(to) end def tons self * TON end alias_method :ton, :tons def weeks self * WEEK end alias_method :week, :weeks def yards self * YARD end alias_method :yard, :yards def years self * YEAR end alias_method :year, :years end