seconds = 356521N.B.: This relies on Ruby's integer division -- dividing an integer by an integer results in an integer, with any fractional remainder discarded.
days = seconds / (24 * 60 * 60)
seconds = seconds % (24 * 60 * 60)
hours = seconds / (60 * 60)
seconds = seconds % (60 * 60)
minutes = seconds / 60
seconds = seconds % 60
My pair and I ended up implementing something very much like this, but it left a bad taste in my mouth. I mean, it works and all, but it feels kind of ... non-functional. Ya know?
So, after much fretting and sleeplessness last night ... behold:
seconds = 356521This version needs to be run in a Rails
days, hours, minutes, seconds =
[1.day, 1.hour, 1.minute, 1.second].inject() do |acc, unit|
quotient, seconds = seconds.divmod unit
acc << quotient
irb, because it makes use of the Rails shortcut definitions of the number of seconds in various units of time. You could easily convert to plain
irb-able Ruby by replacing
1.dayet al above with their numeric equivalents.
The resulting code is both (more) functional, and more quintessentially Ruby-ish.
divmodand multiple assignment let us figure out the quotient and the remainder of the division in one go, and
injectlets us accumulate the results and ultimately multiply assign them to their respective units.
I'm a little bummed, though, that this version has the side effect of destroying the original contents of
seconds, as well as requiring
secondsto be defined outside the scope of the
inject. What would be really cool would be to have a version of
injectthat allowed for multiple accumulators (or, really, a 'decumulator' in this case) such that all side effects could be contained within the