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
advantage : one thread for all the tasks
disadvantage : has to wake up to pool its jobqueue
But your approach is definitely more cute and more 'rubystic'.
Quick question : is the "rescue Interrupt" really needed ? Does it
avoid some "under the carpet thread problems" ?
Best regards,
···
2007/2/23, KCons <consalus@gmail.com>:
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:
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.
<snip>
Hello KCons:
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!
It is interesting! You need to blog about it somewhere so I can bookmark it for later.
Pete Yandell
···
On 23/02/2007, at 5:35 PM, KCons wrote:
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.
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.
cheers.
-a
···
On Fri, 23 Feb 2007, John Mettraux wrote:
--
be kind whenever possible... it is always possible.
- the dalai lama
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.