Module: Ruff::Standard::Call1cc

Defined in:
lib/ruff/standard/call1cc.rb

Overview

Call1cc provides call-with-oneshot-continuation. The continuation can be run in the context.

Examples:

Call1cc.context do
  divfail = lambda { |l, default|
    Call1cc.run {|k|
      l.map{|e|
        if e.zero?
          k.call(default)
        else
          e / 2
        end
      }
    }
  }

  pp divfail.call([1, 3, 5], [1])
  # ==> [0, 1, 2]
  puts '---'
  pp divfail.call([1, 0, 5], [1])
  # ==> [1]
end

Class Method Summary collapse

Class Method Details

.context(&prc) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/ruff/standard/call1cc.rb', line 31

def context(&prc)
  p = Ruff.instance
  @stack.push p

  ret = Ruff.handler
            .on(p) do |k, v|
    k.call(v)
  end
            .run(&prc)

  @stack.pop
  ret
end

.run(&f) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/ruff/standard/call1cc.rb', line 45

def run(&f)
  top = @stack.first
  Ruff.handler
      .on(top) do |_, v|
    # abort the rest of computation from calling the continuation
    top.perform(v)
  end.run do
    f.call(->(v) { top.perform(v) })
  end
end