Class: PryStackExplorer::WhenStartedHook

Inherits:
Object
  • Object
show all
Defined in:
lib/pry-stack_explorer/when_started_hook.rb

Instance Method Summary collapse

Instance Method Details

#call(target, options, _pry_) ⇒ Object


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/pry-stack_explorer/when_started_hook.rb', line 42

def call(target, options, _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 bindings.empty? || !bindings.all? { |v| v.is_a?(Binding) }
      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) ⇒ Object


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/pry-stack_explorer/when_started_hook.rb', line 4

def caller_bindings(target)
  bindings = binding.callers

  start_frames = bindings.each_with_index.select do |b, i|
    b.frame_type == :method &&
      b.eval("self") == Pry &&
      b.eval("__method__") == :start
  end

  start_frame_index = start_frames.first.last

  if start_frames.size >= 2
    idx1, idx2 = start_frames.take(2).map(&:last)

    is_nested_session = bindings[idx1..idx2].detect do |b|
      b.eval("__method__") == :re &&
        b.eval("self.class") == Pry
    end

    start_frame_index = idx2 if !is_nested_session
  end

  bindings = bindings.drop(start_frame_index + 1)

  bindings = bindings.drop(1) if bindings.first.eval("__method__") == :pry
  bindings = bindings.drop_while { |b| b.eval("self.inspect") =~ /PryNav/ }

  # 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