Sha256: 17cd2ce742c46a87b3218ef800356e5c2a5d5bfd3ddf88cceca2864432742d80

Contents?: true

Size: 984 Bytes

Versions: 10

Compression:

Stored size: 984 Bytes

Contents

#START:stack
class CatchStack
  Frame = Struct.new(:symbol, :cc)
  
  def stack
    Thread.current[:catch_stack] ||= []
  end
  
  def wrap(symbol, cc)
    stack << Frame.new(symbol, cc)
    begin
      yield
    ensure
      stack.pop
    end
  end
  
  def find_continuation_for(symbol)
      stack.pop until stack.empty? || stack.last.symbol == symbol
      if stack.empty?
        fail NameError, "uncaught throw `#{sym}'"
      else
        stack.pop.cc
      end
  end
end
#END:stack

#START:CC
module CC
  CATCH_STACK = CatchStack.new
  
  def self.catch(sym)
    callcc do |cc|
      CATCH_STACK.wrap(sym, cc) do
        yield 
      end
    end
  end
  
  def self.throw(sym, value=nil)
    cc = CATCH_STACK.find_continuation_for(sym)
    cc.call(value)
  end
end
#END:CC

#START:body
def test_method
  CC.throw(:x, "thrown X") if rand < 0.5
end

result = CC.catch(:x) do
          test_method
          "normal exit"
        end
        
puts "Result is #{result}"
#END:body

Version data entries

10 entries across 10 versions & 5 rubygems

Version Path
brandon-codex-1.0.3 app_generators/codex/templates/code/control/cc_throw_catch.rb
drnic-codex-1.0.0 app_generators/codex/templates/code/control/cc_throw_catch.rb
drnic-codex-1.0.1 app_generators/codex/templates/code/control/cc_throw_catch.rb
drnic-codex-1.0.2 app_generators/codex/templates/code/control/cc_throw_catch.rb
pragdave-codex-1.0.3 app_generators/codex/templates/code/control/cc_throw_catch.rb
tobias-codex-1.0.3 app_generators/codex/templates/code/control/cc_throw_catch.rb
codex-1.1.2 app_generators/codex/templates/code/control/cc_throw_catch.rb
codex-1.1.1 app_generators/codex/templates/code/control/cc_throw_catch.rb
codex-1.1.0 app_generators/codex/templates/code/control/cc_throw_catch.rb
codex-1.0.2 app_generators/codex/templates/code/control/cc_throw_catch.rb