class PryRescue
@see {Pry::rescue}
want to pollute the Pry namespace with.
The main API is exposed via the Pry object, but here are a load of helpers that I didn’t
raised in your code.
PryRescue provides the ability to open a Pry shell whenever an unhandled exception is
def self.peek!(*)
Called when rescue --peek is used and the user hits
def self.peek!(*) puts 'Preparing to peek via pry!' unless ENV['NO_PEEK_STARTUP_MESSAGE'] require 'pry' unless binding.respond_to?(:of_caller) raise "pry-stack_explorer is not installed" end throw :raise_up, Interrupt if Pry === binding.of_caller(1).eval('self') binding.of_caller(1).pry # TODO pry :call_stack => binding.of_callers, :initial_frame => 1 end
def self.peek_on_signal signal
def self.peek_on_signal signal trap signal, &method(:peek!) end
def current_path?(file)
-
(Boolean)
-
Parameters:
-
file
(String
) -- the absolute path
def current_path?(file) file.start_with?(Dir.pwd) && !file.match(%r(/vendor/)) end
def enter_exception_context(exception)
-
exception
(Exception
) -- The exception raised
def enter_exception_context(exception) @any_exception_captured = true @exception_context_depth ||= 0 @exception_context_depth += 1 exception = exception.instance_variable_get(:@rescue_cause) if phantom_load_raise?(exception) bindings = exception.instance_variable_get(:@rescue_bindings) bindings = without_bindings_below_raise(bindings) bindings = without_duplicates(bindings) with_program_name "#$PROGRAM_NAME [in pry-rescue @ #{Dir.pwd}]" do if defined?(PryStackExplorer) pry :call_stack => bindings, :hooks => pry_hooks(exception), :initial_frame => initial_frame(bindings) else Pry.start bindings.first, :hooks => pry_hooks(exception) end end ensure @exception_context_depth -= 1 end
def gem_path?(file)
-
(Boolean)
-
Parameters:
-
file
(String
) -- the absolute path
def gem_path?(file) # rubygems 1.8 if Gem::Specification.respond_to?(:any?) Gem::Specification.any?{ |gem| file.start_with?(gem.full_gem_path) } # rubygems 1.6 else Gem.all_load_paths.any?{ |path| file.start_with?(path) } end end
def in_exception_context?
-
(Boolean)
-
def in_exception_context? @exception_context_depth && @exception_context_depth > 0 end
def initial_frame(bindings)
-
(Fixnum)
- The offset of the first binding of user code
Parameters:
-
bindings
(Array
) -- All bindings
def initial_frame(bindings) bindings.each_with_index do |binding, i| return i if user_path?(SourceLocation.call(binding)[0]) end 0 end
def load(script, ensure_repl = false)
-
script
(String
) -- The name of the script
def load(script, ensure_repl = false) require File.expand_path('../pry-rescue/kernel_exit_hooks.rb', __FILE__) if ensure_repl Pry::rescue do begin TOPLEVEL_BINDING.eval File.read(script), script, 1 rescue SyntaxError => exception puts "#{exception}\n" end end end
def load_rake(task)
def load_rake(task) require 'rake' Pry::rescue do load "#{Dir.pwd}/Rakefile" Rake::Task[task].invoke end end
def phantom_load_raise?(e)
-
e
(Exception
) -- The raised exception
def phantom_load_raise?(e) bindings = e.instance_variable_get(:@rescue_bindings) bindings.any? && SourceLocation.call(bindings.first)[0] == __FILE__ end
def pry_hooks(ex)
-
ex
(Exception
) -- The exception we're currently looking at
def pry_hooks(ex) hooks = Pry.config.hooks.dup hooks.add_hook(:before_session, :save_captured_exception) do |_, _, _pry_| _pry_.last_exception = ex _pry_.backtrace = ex.backtrace _pry_.sticky_locals.merge!(:_rescued_ => ex) _pry_.exception_handler.call(_pry_.output, ex, _pry_) end hooks end
def stdlib_path?(file)
-
(Boolean)
-
Parameters:
-
file
(String
) -- the absolute path
def stdlib_path?(file) file.start_with?(RbConfig::CONFIG['libdir']) || %w( (eval) <internal:prelude> ).include?(file) end
def user_path?(file)
-
(Boolean)
-
Parameters:
-
file
(String
) -- the absolute path
def user_path?(file) return true if current_path?(file) return false if stdlib_path?(file) || gem_path?(file) true end
def with_program_name name
def with_program_name name before = $PROGRAM_NAME $PROGRAM_NAME = name yield ensure $PROGRAM_NAME = before end
def without_bindings_below_raise(bindings)
-
bindings
(Array
) -- The call stack.
def without_bindings_below_raise(bindings) return bindings if bindings.size <= 1 bindings.drop_while do |b| SourceLocation.call(b)[0] == File.expand_path("../pry-rescue/core_ext.rb", __FILE__) end.drop_while do |b| Interception == b.eval("self") end end
def without_duplicates(bindings)
-
(Array
-)
Parameters:
-
bindings
(Array
) -- The call stack
def without_duplicates(bindings) bindings.zip([nil] + bindings).reject do |b, c| # The eval('__method__') is there as a shortcut as loading a method # from a binding is very slow. c && (b.eval("::Kernel.__method__") == c.eval("::Kernel.__method__")) && Pry::Method.from_binding(b) == Pry::Method.from_binding(c) end.map(&:first) end