Module: Cond

Extended by:
DSL, Wrapping
Defined in:
lib/cond/cond.rb,
lib/cond/error.rb,
lib/cond/handler.rb,
lib/cond/restart.rb,
lib/cond/version.rb,
lib/cond/defaults.rb,
lib/cond/wrapping.rb,
lib/cond/code_section.rb,
lib/cond/message_proc.rb,
lib/cond/thread_local.rb,
lib/cond/dsl_definition.rb,
lib/cond/handling_section.rb,
lib/cond/symbol_generator.rb,
lib/cond/restartable_section.rb

Overview

Resolve errors without unwinding the stack.

Defined Under Namespace

Modules: DSL, SymbolGenerator, Wrapping Classes: CodeSection, ContextError, Defaults, Error, Handler, HandlingSection, MessageProc, NoRestartError, Restart, RestartableSection, ThreadLocal

Constant Summary collapse

VERSION =
"0.3.2"

Class Method Summary collapse

Methods included from Wrapping

wrap_instance_method, wrap_singleton_method

Methods included from DSL

again, handle, handling, invoke_restart, leave, restart, restartable

Class Method Details

.available_restartsObject

The current set of restarts which have been registered.



58
59
60
# File 'lib/cond/cond.rb', line 58

def available_restarts
  restarts_stack.last
end

.check_context(keyword) ⇒ Object

:nodoc:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cond/cond.rb', line 93

def check_context(keyword)  #:nodoc:
  section = Cond.code_section_stack.last
  case keyword
  when :restart
    unless section.is_a? RestartableSection
      Cond.original_raise(
        ContextError,
        "`#{keyword}' called outside of `restartable' block"
      )
    end
  when :handle
    unless section.is_a? HandlingSection
      Cond.original_raise(
        ContextError,
        "`#{keyword}' called outside of `handling' block"
      )
    end
  when :leave, :again
    unless section
      Cond.original_raise(
        ContextError,
        "`#{keyword}' called outside of `handling' or `restartable' block"
      )
    end
  end
end

.find_handler(target) ⇒ Object

Find the closest-matching handler for the given Exception.



65
66
67
# File 'lib/cond/cond.rb', line 65

def find_handler(target)  #:nodoc:
  find_handler_from(handlers_stack.last, target)
end

.find_handler_from(handlers, target) ⇒ Object

:nodoc:



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/cond/cond.rb', line 69

def find_handler_from(handlers, target)  #:nodoc:
  handlers.fetch(target) {
    found = handlers.inject(Array.new) { |acc, (klass, func)|
      index = target.ancestors.index(klass)
      if index
        acc << [index, func]
      else
        acc
      end
    }.sort_by { |t| t.first }.first
    found and found[1]
  }
end

.run_code_section(klass, &block) ⇒ Object

:nodoc:



83
84
85
86
87
88
89
90
91
# File 'lib/cond/cond.rb', line 83

def run_code_section(klass, &block) #:nodoc:
  section = klass.new(&block)
  Cond.code_section_stack.push(section)
  begin
    section.instance_eval { run }
  ensure
    Cond.code_section_stack.pop
  end
end

.with_default_handlersObject

A default handler is provided which runs a simple choose-a-restart input loop when raise is called.



48
49
50
51
52
53
# File 'lib/cond/cond.rb', line 48

def with_default_handlers
  # note: leave unfactored due to notable yield vs &block performance
  with_handlers(defaults.handlers) {
    yield
  }
end

.with_handlers(handlers) ⇒ Object

Register a set of handlers. The given hash is merged with the set of current handlers.

When the block exits, the previous set of handlers (if any) are restored.



17
18
19
20
21
22
23
24
25
# File 'lib/cond/cond.rb', line 17

def with_handlers(handlers)
  # note: leave unfactored due to notable yield vs &block performance
  handlers_stack.push(handlers_stack.last.merge(handlers))
  begin
    yield
  ensure
    handlers_stack.pop
  end
end

.with_restarts(restarts) ⇒ Object

Register a set of restarts. The given hash is merged with the set of current restarts.

When the block exits, the previous set of restarts (if any) are restored.



34
35
36
37
38
39
40
41
42
# File 'lib/cond/cond.rb', line 34

def with_restarts(restarts)
  # note: leave unfactored due to notable yield vs &block performance
  restarts_stack.push(restarts_stack.last.merge(restarts))
  begin
    yield
  ensure
    restarts_stack.pop
  end
end