From: Dingsi Date: 2006-07-17T06:28:56+09:00 Subject: Re: [QUIZ] Negative Sleep (#87) Hi there, Ruby Quiz! Nice to meet you. It's my first time here, so don't be too rude with me :D Err.. well.. here is my solution to the negative sleep issue. I've been highly inspired by MenTaLguY's ( Computation.new { ... } + Sleep.new(-1) + Computation.new { ... } ).run It executes the second computation one second before the first. But I thought the code was a bit redundant. Ruby already has a "Computation"-thing, doesn't it? I just extended Proc to be able to do something like: (proc { ... } + ProcStack.sleep(-1) + proc { ... }).call Looks cleaner IMO. ProcStack.sleep(-1) returns more or less a "proc { sleep 1 }" with a little meta-information appended which informs our ProcStack-instance (created by Proc#+) that the sleep as well as the following proc should be executed before the previous proc. I hope you all understood... my english isn't the best and even in my native language (german, btw) I suck at explaining things. Gah, just read the code. ^^ #------------------------------------------------------------------------------- # time machine, whee! class NegativeProc < Proc; end class ProcStack def initialize(*args) @negative = args.shift if args.first == true @stack = args end def + code new_stack = @stack.dup if code.is_a? NegativeProc new_stack.insert(-2, code) new_stack.unshift(true) elsif code.respond_to? 'call' if @negative new_stack.insert(-3, code) else new_stack.push(code) end end ProcStack.new(*new_stack) end def call @stack.each { |p| p.call } end def ProcStack.sleep(time) if time < 0 NegativeProc.new { Kernel.sleep(time.abs) } else Proc.new { Kernel.sleep(time) } end end end class Proc def + code ProcStack.new(self) + code end end # should print something like "chunky ... bacon\hooray for foxes" whee = proc { print "bacon\n" } + ProcStack.sleep(-2) + proc { print "chunky " } + ProcStack.sleep(1) + proc { print "hooray for " } + proc { print "foxes" } whee.call #------------------------------------------------------------------------------- Well.. I know the solution has weaknesses and could be extended. (This @negative-thingy is quite an ugly hack, but I don't see a better way ATM) Also I have something like free movable code in my mind: proc { omg } + proc(-1) { wtf } + proc(1) { bbq } + proc { lol } which would evaluate to: wtf; omg; lol; bbq Would be funny to maintain such source, wouldn't it? But since the current code does all work asked for in the quiz I'm satisfied with it. ~dingsi