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