Created
October 26, 2011 08:38
-
-
Save headius/1315794 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RESET_STACK = [] | |
SHIFT_MAP = {} | |
def reset(&block) | |
RESET_STACK.push block | |
block.call() | |
ensure | |
RESET_STACK.pop | |
end | |
def shift(&block) | |
if SHIFT_MAP.key? block.source_location | |
ary = SHIFT_MAP[block.source_location] | |
value = ary.pop | |
SHIFT_MAP.delete(block.source_location) if ary.empty? | |
value | |
else | |
shift_proc = proc do |arg| | |
SHIFT_MAP[block.source_location] ||= [] | |
SHIFT_MAP[block.source_location].push arg | |
RESET_STACK[-1].call | |
end | |
block.call(shift_proc) | |
end | |
end | |
p reset { 2 * 2 } # 4 | |
p reset { 2 * shift {|k| 2 } } # 4 | |
p reset { 2 * shift {|k| k[2] } } # 8 | |
p reset { 2 * shift {|k| k[k[2]] } } # 16 | |
p reset { 2 * shift {|k| k[shift {|j| j[3]}] } } # 24 | |
p reset { 2 * shift {|k| k[3] + k[4]} } # 28 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm interested in understanding more about shift-reset and was looking for more interesting examples where it would be useful and came across Christian's article.
Then I was trying to work out how the two implementations differed and why his example didn't work with your implementation. Stepping through the code in the different implementations was a bit of a mind-bender. Haven't used continuations in Ruby before.
Does the way you've implemented shift-reset prevent creating some kind of lazy forkable iterator similar to what Christian made with
each_to_stream(collection)
?