mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
47 lines
1.3 KiB
Ruby
47 lines
1.3 KiB
Ruby
require 'continuation' if RUBY_VERSION.to_f >= 1.9
|
|
|
|
class Exception
|
|
attr_accessor :continuation
|
|
|
|
def restart(&block)
|
|
continuation.call block
|
|
end
|
|
end
|
|
|
|
module RaisePlus
|
|
alias :original_raise :raise
|
|
|
|
private
|
|
|
|
def raise(*args)
|
|
exception = case
|
|
when args.size == 0
|
|
$!.nil? ? RuntimeError.exception : $!
|
|
when args.size == 1 && args[0].is_a?(String)
|
|
RuntimeError.exception(args[0])
|
|
when args.size == 2 && args[0].is_a?(Exception)
|
|
args[0].exception(args[1])
|
|
when args[0].is_a?(Class) && args[0].ancestors.include?(Exception)
|
|
args[0].exception(args[1])
|
|
else
|
|
args[0]
|
|
end
|
|
|
|
# passing something other than a String or Exception is illegal, but if someone does it anyway,
|
|
# that object won't have backtrace or continuation methods. in that case, let's pass it on to
|
|
# the original raise, which will reject it
|
|
return super exception unless exception.is_a?(Exception)
|
|
|
|
# keep original backtrace if reraising
|
|
exception.set_backtrace(args.size >= 3 ? args[2] : caller) if exception.backtrace.nil?
|
|
|
|
blk = callcc do |cc|
|
|
exception.continuation = cc
|
|
super exception
|
|
end
|
|
blk.call unless blk.nil?
|
|
end
|
|
|
|
alias :fail :raise
|
|
end
|