| 
									
										
										
										
											2013-02-06 18:46:36 -06:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-06 18:51:35 -06:00
										 |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-06 18:46:36 -06:00
										 |  |  |   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 |