Hi,
I tried to keep it simple. The code blocks in an Insomnia object are
assumed to be executed infinitely fast. Sleeping a negative amount means
that the following block is run before the preceding block.
Code blocks are stored in a hash where the key is the relative time
(@t) and the
value is an array of Proc objects. The run method simply sorts by
time and calls
the procs after sleeping (Kernel) the required number of seconds.
Cheers,
Boris
class Insomnia
# It's really sick to call this method 'do',
# but I can't think of a better name...
def do(&block)
@blocks[@t] << block
end
def sleep(seconds)
@t += seconds
end
def run
times = @blocks.keys.sort
t_now = times.min
times.each do |t|
Kernel.sleep(t - t_now)
t_now = t
@blocks[t].each {|b| b.call}
end
end
def initialize
@blocks = Hash.new {|h, t| h[t] = []}
@t = 0
yield(self)
run
end
end
Insomnia.new do |i|
i.do { puts "Something will explode in ten seconds:" }
i.sleep(10)
i.do { puts "Boom!" }
# countdown:
1.upto(9) do |num|
i.sleep(-1)
i.do { puts num.to_s }
end
end