From: "Guy N. Hurst" Date: 2000-12-20T16:22:38+09:00 Subject: [ruby-talk:7750] Re: Code sample for improvement Stephen White wrote: > > During an idle chat with someone on IRC, they presented some fairly > nasty code for printing a time interval in English. I cleaned it up > a bit and converted it to Ruby. > > > Example run: > > [steve@localhost steve]$ ./a 10000 > 2 hours 46 mins 40 secs > > I was interested in how the new constructs available in Ruby, like > closures and co-routines, could help clean up what really is pretty > ghastly code. > > I've played around with a few other approaches, but nothing really > seems to stand out as being a better way of doing things. > I looked at the other samples and decided to give this a try. I figured there might be a nice way to use the Time class for this. Besides, there aren't 30 days in every month ;-) In making this code, I am taking advantage of the fact that the English words, including your accepted abbreviations "min" and "sec", match the methods I will use from the Time class, which I use as my workhorse. No tables are needed. Since this seems like a useful method, I added it into the String and Integer classes. interv.rb======== class String def plural(q) if q==1 then self else self+"s" end end def to_time parts=%w(year month day hour min sec) tc = Time.mktime(1970,1,1,0,0,0) tn = Time.at(self.to_i + tc.to_i) s = "" parts.each {|part| q=tn.send(part)-tc.send(part); s += q.to_s + " " + part.plural(q) + " " unless q<1 } s.chop end end class Integer def to_time self.to_s.to_time end end ================== require 'interv.rb' time = ARGV[0] || (print "Interval: "; gets) puts time.to_time puts 10000.to_time # 2 hours 46 mins 40 secs puts "10000".to_time # 2 hours 46 mins 40 secs puts "four".to_time # "" puts 0x6f.to_time # 1 min 51 secs Personally, I think this better reflects the Ruby way to do things. I really like Ruby :-) Guy N. Hurst -- HurstLinks Web Development http://www.hurstlinks.com/ Norfolk, VA - (757)623-9688 PHP/MySQL - Ruby/Perl - HTML/Javascript