class PryStackExplorer::WhenStartedHook

Public Instance Methods

call(target, options, _pry_) click to toggle source
# File lib/pry-stack_explorer/when_started_hook.rb, line 23
def call(target, options, _pry_)
  target ||= _pry_.binding_stack.first if _pry_
  options = {
    :call_stack    => true,
    :initial_frame => 0
  }.merge!(options)

  return if !options[:call_stack]

  if options[:call_stack].is_a?(Array)
    bindings = options[:call_stack]

    if !valid_call_stack?(bindings)
      raise ArgumentError, ":call_stack must be an array of bindings"
    end
  else
    bindings = caller_bindings(target)
  end

  PryStackExplorer.create_and_push_frame_manager bindings, _pry_, :initial_frame => options[:initial_frame]
end
caller_bindings(target) click to toggle source
# File lib/pry-stack_explorer/when_started_hook.rb, line 5
def caller_bindings(target)
  bindings = binding.callers

  bindings = remove_internal_frames(bindings)
  bindings = remove_debugger_frames(bindings)
  bindings = bindings.drop(1) if pry_method_frame?(bindings.first)

  # Use the binding returned by #of_caller if possible (as we get
  # access to frame_type).
  # Otherwise stick to the given binding (target).
  if !PryStackExplorer.bindings_equal?(target, bindings.first)
    bindings.shift
    bindings.unshift(target)
  end

  bindings
end

Private Instance Methods

internal_frames_with_indices(bindings) click to toggle source

@return [Array<Array<Binding, Fixnum>>]

# File lib/pry-stack_explorer/when_started_hook.rb, line 84
def internal_frames_with_indices(bindings)
  bindings.each_with_index.select do |b, i|
    b.frame_type == :method &&
      safe_send(b.eval("self"), :equal?, Pry) &&
      safe_send(b.eval("__method__"), :==, :start)
  end
end
nested_session?(bindings) click to toggle source

When a pry session is started within a pry session @return [Boolean]

# File lib/pry-stack_explorer/when_started_hook.rb, line 76
def nested_session?(bindings)
  bindings.detect do |b|
    safe_send(b.eval("__method__"), :==, :re) &&
      safe_send(b.eval("self.class"), :equal?, Pry)
  end
end
pry_method_frame?(binding) click to toggle source

binding.pry frame @return [Boolean]

# File lib/pry-stack_explorer/when_started_hook.rb, line 70
def pry_method_frame?(binding)
  safe_send(binding.eval("__method__"), :==, :pry)
end
remove_debugger_frames(bindings) click to toggle source

remove pry-nav / pry-debugger / pry-byebug frames

# File lib/pry-stack_explorer/when_started_hook.rb, line 64
def remove_debugger_frames(bindings)
  bindings.drop_while { |b| b.source_location[0] =~ /pry-(?:nav|debugger|byebug)/ }
end
remove_internal_frames(bindings) click to toggle source

remove internal frames related to setting up the session

# File lib/pry-stack_explorer/when_started_hook.rb, line 48
def remove_internal_frames(bindings)
  start_frames = internal_frames_with_indices(bindings)
  return bindings if start_frames.empty?

  start_frame_index = start_frames.first.last

  if start_frames.size >= 2
    # god knows what's going on in here
    idx1, idx2 = start_frames.take(2).map(&:last)
    start_frame_index = idx2 if !nested_session?(bindings[idx1..idx2])
  end

  bindings.drop(start_frame_index + 1)
end
valid_call_stack?(bindings) click to toggle source
# File lib/pry-stack_explorer/when_started_hook.rb, line 92
def valid_call_stack?(bindings)
  bindings.any? && bindings.all? { |v| v.is_a?(Binding) }
end