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:
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
Neat, that’ll certainly come in handy when I’m doing more complicated
scheduling.
Clean interface, too.
Quick question : is the “rescue Interrupt” really needed ? Does it
avoid some “under the carpet thread problems” ?
Y’know, I imagine the ‘rescue Interrupt’ business is not actually
needed. It is just there because I got seeing exception dumps when I
Ctrl-C’d out of the sleep.
it seems like a single threaded/processed scheduler is an imposibility?
nevertheless i’ve already found a use for this code in a situation where
i
don’t care if events are fired precisely (as is possible) as i declare
them or
not.
it seems like a single threaded/processed scheduler is an imposibility?
Hey, thanks for the light, I’ll fix that / make it better.
I’ll have to correct from “one thread for all tasks” to something like
“one thread as an alarm clock for all tasks”.
nevertheless i’ve already found a use for this code in a situation where i
don’t care if events are fired precisely (as is possible) as i declare them or
not.
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.
It is interesting! You need to blog about it somewhere so I can
bookmark it for later.
Wow… I’m just (8 hours into both) learning Python and Ruby and I
didn’t realize how powerful / extensible Ruby was until I saw your
example. Great stuff!
Thanks,
Michael
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.