From: KCons Date: 2007-02-23T15:35:06+09:00 Subject: Cute little simple scheduling code hack I'm sure there is some far superior prior art out there somewhere, but this is a useful little hack I threw together today that I thought someone else might find interesting. I wanted to do a little task every few seconds for some duration of time, and after a bit of overkill I came up with a little library that lets me do stuff like: every( 5.seconds ).for( 2.days ) { puts "Chunky bacon, k?" } or every( 2.minutes ).until ( Time.now + 4.hours ) { dance_for_a_while } or even class String def gradual_out( n = 1 ) ix = 0 every( n.seconds ).unless(lambda {ix >= size}) do print self[ix].chr ix += 1 end end end "Tuesday is the new Thursday".gradual_out( 400.milliseconds ) Fun to play with. Again, just a quick hack, so if you see any glaring issues or useful improvements, let me know, because I'm sure I'll find use for it again later. --Code below-- class Scheduler def initialize( int ) @interval = int end def for( secs ) self.until( Time.now + secs ) { |x| yield x } end def until( endtime ) self.unless( lambda { Time.now >= endtime } ) { |x| yield x } end def unless( cond ) while !cond.call do current = Time.now yield current wait_time = (current + @interval) - Time.now begin sleep( wait_time ) unless wait_time <= 0 or cond.call rescue Interrupt break end end end end module Kernel def every( int ) Scheduler.new( int ) end end class Numeric def seconds; self; end def minutes; self * 60; end def hours; self.minutes * 60; end def milliseconds; self / 1000.0; end def days; self.hours * 24; end end