Module: DynamicWind

Defined in:
lib/dynamicwind.rb

Defined Under Namespace

Classes: Stack

Constant Summary collapse

VERSION =
'1.0.1'

Instance Method Summary collapse

Instance Method Details

#__callcc_origObject



11
# File 'lib/dynamicwind.rb', line 11

alias __callcc_orig callcc

#__switch(mark) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/dynamicwind.rb', line 43

def __switch(mark)
  return if __top.equal?(mark)
  __switch(mark.next)
  fst, snd = mark.fst, mark.snd
  __callcc_orig {|c| fst.first.call(c) } if fst.first
  __top.fst = snd
  __top.snd = fst
  __top.next = mark
  self.__top = mark
  __top.fst = nil
  __top.snd = nil
  __top.next = nil
  __callcc_orig {|c| fst.last.call(c) } if fst.last
end

#__topObject



35
36
37
# File 'lib/dynamicwind.rb', line 35

def __top
  Thread.current[:dynamicwind_stack] ||= Stack.new
end

#__top=(x) ⇒ Object



39
40
41
# File 'lib/dynamicwind.rb', line 39

def __top=(x)
  Thread.current[:dynamicwind_stack] = x
end

#callccObject



13
14
15
16
17
18
# File 'lib/dynamicwind.rb', line 13

def callcc
  mark = __top
  __callcc_orig do |ctn|
    yield(proc {|*ret| __switch(mark); ctn.call(*ret) })
  end
end

#dynamicwind(before, thunk, after) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/dynamicwind.rb', line 20

def dynamicwind(before, thunk, after)
  before_ = after_ = nil
  if ctn_before = __callcc_orig {|c| before_ = c; false }
    before.call
    ctn_before.call
  end
  if ctn_after = __callcc_orig {|c| after_ = c; false }
    after.call
    ctn_after.call
  end
  mark = __top
  __switch(Stack[[before_, nil], [nil, after_], mark])
  thunk.call ensure __switch(mark)
end