From: "Aleksi Niemelä" Date: 2000-12-20T05:20:47+09:00 Subject: [ruby-talk:7712] RE: Code sample for improvement > During an idle chat with someone on IRC Welcome to #ruby-lang (at least on IRCNET). There's almost always someone (Japan, Europe, States, and again). > ..they presented some fairly nasty code for printing > a time interval in English Here's my table driven shot. I tried to remove the logic for 's' suffixing, but in the end there was more code to initialize the array. It might be a little bit prettier to use real if instead of and-idiom. > I was interested in how the new constructs available in Ruby I'm sorry not to use any fancy constructs, but I simply don't see any use for them in here. Please forgive me if two of the lines are too long. #! /usr/bin/env ruby # Given the number of seconds, convert to English description def format(time) res = "" [ ["sec", 60], ["min", 60], ["hour", 24], ["day", 30], ["month", 12], ["year", 1]].each do |name, unit| time > 0 and res = " #{time%unit} #{name}#{time%unit == 1 ? '' : 's'}" + res time /= unit end res end time = ARGV[0].to_i puts format(time) The problem with this solution is that always that something is printed there will be a leading whitespace. To get rid of that we could forget the string building and instead collect the parts and print them out. (Had I chosen shorter names the if could be in modifier form instead of this full-blown form.) def format(time) parts = [] [ ["sec", 60], ["min", 60], ["hour", 24], ["day", 30], ["month", 12], ["year", 1]].each do |name, unit| if time > 0 parts << "#{time%unit} #{name}#{time%unit == 1 ? '' : 's'}" end time /= unit end parts.reverse.join ' ' end To tell something how I ended up with this code I could say that the beautiful way you presented your code lead me immediately to the table driven solution: secs = time % 60; time = time / 60 mins = time % 60; time = time / 60 hours = time % 24; time = time / 24 days = time % 30; time = time / 30 months = time % 12; time = time / 12 years = time res = "" res += format(years, 'year', 'years') res += format(months, 'month', 'months') res += format(days, 'day', 'days') res += format(hours, 'hour', 'hours') res += format(mins, 'min', 'mins') res += format(secs, 'sec', 'secs') There are two easily seen tables. First one with the divisioning and second one with naming. Further it could be seen that all plural forms are the same as singular plus 's'. After that it's just layouting. In any case the interface should be like it is on my version. It's all up to method format how to do the magic. It could be implemented on your way, or mine. As a commentary to original problem, I'd like to ask is it really meant that the output with 0 is an empty string or was it just a simplification? - Aleksi