* Ruby Quiz <james / grayproductions.net> [060714 07:49]: > You could also view a sleep as specifying the relationship between > the computations on either side of it. In that case, sleep(1) might > request that the second computation begin at least a second after > the completion of the first one. Negative sleeps would simply > reverse the order of the two computations, sleep(-1) meaning that > the first computation should begin at least a second after the > completion of the second. Alright, I basically took that definition of negative sleep, although I had to decide what should happen when there are three or more statements separated by negative sleeps and what should happen if a negative sleep is before after everything else. I decided both arbitrarily. I decided to implement it as a class that takes procs and runs them in the right order, which I think came out pretty cleanly. -- Mitchell Koch #! /usr/bin/env ruby # # Negative sleep via time machine # Author: Mitchell Koch # # Definition of negative sleep: the statement after the sleep call is # run that many seconds before the statement before the call, meaning # that is equivalent to the order of the two statements as well as the # sign of the number of seconds to sleep both being inverted. # # If there are three or more statements with negative sleeps between # them, they should be inverted two at a time from top to bottom. # # Using negative sleep before or after everything else is called is # undefined and raises errors here. class TimeMachine def initialize @statements = [] yield self end # Give the machine something to do def do(&proc) @statements << proc if @swapidx if @swapidx < 0 # calling at beginning error raise "Cannot warp time before anything else is called" end # swap the last statement and the one before the sleep call @statements[-1], @statements[@swapidx] = @statements[@swapidx], @statements[-1] @swapidx = false end end # Define the time between two events def sleep(n) @swapidx = @statements.size-1 if n < 0 @statements << Proc.new { Kernel.sleep n.abs } end # Activate the machine def run if @swapidx # calling at end error raise "Cannot warp time after everything else is called" end @statements.each { |s| s.call } end end # For minus one seconds, # wuh? # sleep... TimeMachine.new do |t| t.do { puts "sleep..." } t.sleep -1 t.do { puts "For minus one seconds, " } t.sleep -1 t.do { puts "wuh?" } end.run