In Ruby you have callcc
, throw
/ catch
and raise
/ rescue
/ ensure
.
throw
terminates the block with ensure
begin executed:
catch(:done) {
begin
puts "before"
throw :done
puts "after" # will not be called
ensure
puts "ensure"
end
}
produces:
before
ensure
callcc
terminates the block with ensure
begin skipped:
callcc { |cc|
begin
puts "before"
cc.call
puts "after" # will not be called
ensure
puts "ensure" # will not be called
end
}
produces:
before
Another example storing the Continuation
object inside a global variable:
begin
puts "before"
callcc { |cc| $cc = cc }
puts "after"
ensure
puts "ensure"
end
$cc.call
produces:
before
after
ensure
after
ensure
after
...