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!(*)

or sends whichever signal is configured.
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)

Returns:
  • (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)

Parameters:
  • 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)

Returns:
  • (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?

Returns:
  • (Boolean) -
def in_exception_context?
  @exception_context_depth && @exception_context_depth > 0
end

def initial_frame(bindings)

Returns:
  • (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)

Parameters:
  • 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)

Parameters:
  • 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)

Parameters:
  • 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)

Returns:
  • (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)

Returns:
  • (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)

Parameters:
  • 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)

Returns:
  • (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