Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added pryception.rb and examples/ folder

  • Loading branch information...
commit c53edcd0c08180b4b401feb483cb0c1ee933b41e 1 parent 719c8b6
@banister banister authored
View
12 Rakefile
@@ -1,4 +1,5 @@
+desc "Compile *.c files"
task :compile do
cd 'ext/' do
sh 'ruby extconf.rb'
@@ -6,6 +7,17 @@ task :compile do
end
end
+desc "Run example"
+task :example do
+ sh "ruby -I./lib/ ./examples/example.rb "
+end
+
+desc "Run example 2"
+task :example2 do
+ sh "ruby -I./lib/ ./examples/example2.rb "
+end
+
+desc "Run tests"
task :test do
sh 'rspec spec -r ./spec/spec_helpers.rb'
end
View
21 examples/example.rb
@@ -0,0 +1,21 @@
+$:.unshift File.expand_path '../../lib', __FILE__
+require 'pryception'
+
+Interception.prycept do
+
+ def a
+ begin
+ begin
+ raise "foo"
+
+ rescue => e
+ raise "bar"
+ end
+
+ rescue => e
+ 1 / 0
+
+ end
+ end
+ a
+end
View
20 examples/example2.rb
@@ -0,0 +1,20 @@
+$:.unshift File.expand_path '../../lib', __FILE__
+require 'pryception'
+
+def alpha
+ x = 1
+ beta
+end
+
+def beta
+ y = 30
+ gamma(1, 2)
+end
+
+def gamma(x)
+ greeting = x
+end
+
+Interception.prycept do
+ alpha
+end
View
2  lib/cross_platform.rb
@@ -61,7 +61,7 @@ def hook
else #MRI
- require File.expand_path('../../ext/interception.so', __FILE__)
+ require File.expand_path('../../ext/interception', __FILE__)
end
end
View
66 lib/pryception.rb
@@ -0,0 +1,66 @@
+require 'rubygems'
+require 'interception'
+require 'pry'
+
+begin
+ require 'pry-stack_explorer'
+rescue LoadError
+end
+
+module Interception
+
+ class << self
+
+ # Intercept all exceptions that arise in the block and start a Pry session
+ # at the fail site.
+ def prycept(&block)
+ raised = []
+
+ Interception.listen(block) do |exception, binding|
+ if defined?(PryStackExplorer)
+ raised << [exception, binding.callers]
+ else
+ raised << [exception, Array(binding)]
+ end
+ end
+
+ ensure
+ if raised.any?
+ exception, bindings = raised.last
+ enter_exception_context(exception, bindings)
+ end
+ end
+
+ private
+
+ # Sanitize the call stack.
+ # @param [Array<Binding>] bindings The call stack.
+ def prune_call_stack!(bindings)
+ bindings.delete_if { |b| b.eval("self") == self || b.eval("__method__") == :prycept }
+ end
+
+ # Start a Pry session in the context of the exception.
+ # @param [Exception] exception The exception.
+ # @param [Array<Binding>] bindings The call stack.
+ def enter_exception_context(exception, bindings)
+ inject_local("_ex_", exception, bindings.first)
+ inject_local("_raised_", [exception, bindings.first], bindings.first)
+
+ prune_call_stack!(bindings)
+ if defined?(PryStackExplorer)
+ pry :call_stack => bindings
+ else
+ bindings.first.pry
+ end
+ end
+
+ # Inject a local variable into a binding.
+ def inject_local(var, object, binding)
+ Thread.current[:__intercept_var__] = object
+ binding.eval("#{var} = Thread.current[:__intercept_var__]")
+ ensure
+ Thread.current[:__intercept_var__] = nil
+ end
+ end
+end
+
Please sign in to comment.
Something went wrong with that request. Please try again.