class Subunit
Attributes
to_a[R]
to_h[R]
to_i[R]
Public Class Methods
hms_to_seconds(obj)
click to toggle source
e.g. Subunit.hms_to_seconds
('5 minutes and 4 seconds')
> 304 ¶ ↑
# File lib/subunit.rb, line 26 def self.hms_to_seconds(obj) new(units={hours:60, minutes:60,seconds: 60, }, obj).to_i end
new(raw_units={}, obj)
click to toggle source
# File lib/subunit.rb, line 32 def initialize(raw_units={}, obj) @debug = false @raw_units = raw_units accumulate = ->(a) { len = raw_units.to_a.length val = ([0]*(len-1) + a).slice(-(len), len).zip(raw_units.values)\ .inject(0) {|r,x| r * x[1] + x[0] } } if obj.is_a? String @to_i = accumulate.call obj.split(/\D+/).map(&:to_i) elsif obj.is_a? Array then @to_i = accumulate.call obj else raw_subunit = obj || 0 method((raw_units.class.to_s.downcase + '_units').to_sym)\ .call(raw_units, raw_subunit) end end
seconds(val, units: nil)
click to toggle source
# File lib/subunit.rb, line 19 def self.seconds(val, units: nil) new(units={minutes:60, hours:60, days:24}, seconds: val) end
Public Instance Methods
strfunit(s)
click to toggle source
usage: Subunit.new
(units={minutes:60, hours:60}, seconds: 661)\
.strfunit("%x") #=> 11m 1s
%x e.g. 11m 1s %xi e.g. 11m %X e.g. 11 minutes 1 second %Xi e.g. 11 minutes %c e.g. 00:11:01 %s e.g. 11m # returns the 1st most significant value while
ignoring the remainder
# File lib/subunit.rb, line 73 def strfunit(s) # The i switch postfixed to the x or X switch will format the output # without seconds unless there are no minutes. s.sub!(/%xi?/) do |x| h = to_h a = h.to_a a2 = (a.length > 1 and x[-1][/i$/] and h[:seconds]) ? a[0..-2] : a a2.map {|label, val| val.to_s + label[0]}.join(' ') end s.sub!(/%Xi?/) do |x| h = to_h a = h.to_a a2 = (a.length > 1 and x[-1][/i$/] and h[:seconds]) ? a[0..-2] : a a2.map do |label, val| next if val == 0 label2 = val > 1 ? label.to_s : label.to_s.sub(/s$/,'') val.to_s + ' ' + label2 end.compact.join(' ') end s.sub!('%c') do |x| a = @raw_units.values.reverse a << a[-1] fmt = a.map {|v| "%0" + v.to_s.length.to_s + "d"}.join(":") fmt % to_a end s.sub!('%s') do |x| label, val = to_h.first val.to_s + label[0] end s end
to_s(omit: [], verbose: true)
click to toggle source
# File lib/subunit.rb, line 120 def to_s(omit: [], verbose: true) if not verbose then r = self.to_a.reverse.take_while {|x| x > 0}.reverse\ .map {|x| "%02d" % x}.join(':') if r.length < 2 then return '00:00' elsif r.length == 2 return '00:' + r else return r end end h = @to_h omit.each {|x| h.delete x} list = h.to_a n = list.find {|_,v| v > 0 } a = list[list.index(n)..-1].map {|x|"%d %s" % x.reverse} duration = case a.length when 1 a.first when 2 a.join ' and ' else "%s and %s" % [a[0..-2].join(', '), a[-1]] end duration.gsub(/(\b1 \w+)s/, '\1') end
Private Instance Methods
array_units(raw_units=[], u=nil)
click to toggle source
# File lib/subunit.rb, line 185 def array_units(raw_units=[], u=nil) val, label = method((u.class.to_s.downcase + '_subunit').to_sym).call(u) units = multiply_units(raw_units).reverse @to_a = scan_units(units, val).map(&:to_i) end
fixnum_subunit(v)
click to toggle source
# File lib/subunit.rb, line 164 def fixnum_subunit(v) [v, :remainder] end
hash_subunit(h)
click to toggle source
# File lib/subunit.rb, line 160 def hash_subunit(h) [h.values.first, h.keys.first] end
hash_units(raw_units={}, u=nil)
click to toggle source
# File lib/subunit.rb, line 172 def hash_units(raw_units={}, u=nil) val, label = method((u.class.to_s.downcase + '_subunit').to_sym).call(u) units = multiply_units(raw_units.values).reverse puts 'units: ' + units.inspect if @debug @to_a = a = scan_units(units, val).map(&:to_i) puts 'a: ' + a.inspect if @debug pairs = (raw_units.keys.reverse + [label]).reverse.take(a.length)\ .reverse.zip(a).select {|x| x[1] > 0} @to_h = Hash[pairs] end
integer_subunit(v)
click to toggle source
# File lib/subunit.rb, line 168 def integer_subunit(v) [v, :remainder] end
multiply_units(x)
click to toggle source
# File lib/subunit.rb, line 191 def multiply_units(x) x.inject([]){|r,x| r + [x.to_i * (r[-1] || 1)]} end
scan_units(unit_list,raw_subunit)
click to toggle source
# File lib/subunit.rb, line 193 def scan_units(unit_list,raw_subunit) n = unit_list.shift unit, subunit = [:/,:%].map{|x| raw_subunit.send x, n} unit_list.length > 0 ? [unit] + scan_units(unit_list, subunit) : [unit, subunit] end