Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Feb 27th, 2012  |  syntax: None  |  size: 1.32 KB  |  views: 21  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. # I got this idea from http://mihai.bazon.net/blog/redis-client-library-javascript-node
  2. # The technique relies on the fact that raising an exception clears the call stack.
  3. # The context is passed along with a block attached to an exception.
  4. # I thought it was brilliant js hackery so I decided to try my hand at it in ruby.
  5. # I've also included some other stack-dependent implementations.
  6.  
  7. # straight recursion, not quite a tail-call
  8. # I can't go above 8.1k without stack error
  9. def rsum(num)
  10.   if num == 0
  11.     0
  12.   else
  13.     num + rsum(num - 1)
  14.   end
  15. end
  16.  
  17. # tail-call block based recursion
  18. # I can't go above 7.6k without stack error
  19. def crsum(num, total = 0, &block)
  20.   if num == 0
  21.     yield total
  22.   else
  23.     crsum(num - 1, num + total, &block)
  24.   end
  25. end
  26.  
  27. # Using blocks and exceptions to clear call stack
  28. class Beer < RuntimeError
  29.   attr_accessor :block
  30.   def initialize(&block)
  31.     @block = block
  32.   end
  33. end
  34.  
  35. def cheers!(&block)
  36.   raise Beer.new(&block)
  37. end
  38.  
  39. def cc(&block)
  40.   loop do
  41.     begin
  42.       block.call
  43.       break
  44.     rescue Beer => beer
  45.       block = beer.block
  46.     end
  47.   end
  48. end
  49.  
  50. def sum(num, total = 0, &block)
  51.   if num == 0
  52.     yield total
  53.   else
  54.     cheers! { sum(num - 1, num + total, &block) }
  55.   end
  56. end
  57.  
  58. cc { sum(100) {|t| puts t} }
  59.  
  60. # Run this block in irb.
  61. # I got up to 100k and it still works!
  62. # cc { sum(1000) {|total| puts total} }
clone this paste RAW Paste Data