Module: PryStackExplorer

Defined in:
lib/pry-stack_explorer.rb,
lib/pry-stack_explorer/version.rb,
lib/pry-stack_explorer/commands.rb,
lib/pry-stack_explorer/frame_manager.rb,
lib/pry-stack_explorer/when_started_hook.rb

Defined Under Namespace

Modules: FrameHelpers Classes: FrameManager, WhenStartedHook

Constant Summary

VERSION =
"0.3.3"
Commands =
Pry::CommandSet.new do
  create_command "up", "Go up to the caller's context. Accepts optional numeric parameter for how many frames to move up." do
    include FrameHelpers

    banner <<-BANNER
      Usage: up [OPTIONS]
        Go up to the caller's context. Accepts optional numeric parameter for how many frames to move up.
        e.g: up
        e.g: up 3
    BANNER

    def process
      inc = args.first.nil? ? 1 : args.first.to_i

      if !frame_manager
        raise Pry::CommandError, "Nowhere to go!"
      else
        frame_manager.change_frame_to frame_manager.binding_index + inc
      end
    end
  end

  create_command "down", "Go down to the callee's context. Accepts optional numeric parameter for how many frames to move down." do
    include FrameHelpers

    banner <<-BANNER
      Usage: down [OPTIONS]
        Go down to the callee's context. Accepts optional numeric parameter for how many frames to move down.
        e.g: down
        e.g: down 3
    BANNER

    def process
      inc = args.first.nil? ? 1 : args.first.to_i

      if !frame_manager
        raise Pry::CommandError, "Nowhere to go!"
      else
        if frame_manager.binding_index - inc < 0
          raise Pry::CommandError, "At bottom of stack, cannot go further!"
        else
          frame_manager.change_frame_to frame_manager.binding_index - inc
        end
      end
    end
  end

  create_command "show-stack", "Show all frames" do
    include FrameHelpers

    banner <<-BANNER
      Usage: show-stack [OPTIONS]
        Show all accessible stack frames.
        e.g: show-stack -v
    BANNER

    def options(opt)
      opt.on :v, :verbose, "Include extra information."
    end

    def process
      if !frame_manager
        output.puts "No caller stack available!"
      else
        content = ""
        content << "\n#{text.bold('Showing all accessible frames in stack:')}\n--\n"

        frame_manager.each_with_index do |b, i|
          if i == frame_manager.binding_index
            content << "=> ##{i} #{frame_info(b, opts[:v])}\n"
          else
            content << "   ##{i} #{frame_info(b, opts[:v])}\n"
          end
        end

        stagger_output content
      end
    end

  end

  create_command "frame", "Switch to a particular frame. Accepts numeric parameter for the target frame to switch to (use with show-stack). Negative frame numbers allowed." do
    include FrameHelpers

    banner <<-BANNER
      Usage: frame [OPTIONS]
        Switch to a particular frame. Accepts numeric parameter for the target frame to switch to (use with show-stack). Negative frame numbers allowed.
        When given no parameter show information about the current frame.

        e.g: frame 4   #=> jump to the 4th frame
        e.g: frame -2  #=> jump to the second-to-last frame
        e.g: frame     #=> show information info about current frame
    BANNER

    def process
      if !frame_manager
        raise Pry::CommandError, "nowhere to go!"
      else

        if args[0]
          frame_manager.change_frame_to args[0].to_i
        else
          output.puts "##{frame_manager.binding_index} #{frame_info(target, true)}"
        end
      end
    end
  end
end

Class Method Summary (collapse)

Class Method Details

+ (Boolean) bindings_equal?(b1, b2)

Simple test to check whether two Binding objects are equal.

Parameters:

  • b1 (Binding)

    First binding.

  • b2 (Binding)

    Second binding.

Returns:

  • (Boolean)

    Whether the Bindings are equal.



109
110
111
112
113
114
# File 'lib/pry-stack_explorer.rb', line 109

def bindings_equal?(b1, b2)
  (b1.eval('self') == b2.eval('self')) &&
    (b1.eval('__method__') == b2.eval('__method__')) &&
    (b1.eval('local_variables').map { |v| b1.eval("#{v}") } ==
     b2.eval('local_variables').map { |v| b2.eval("#{v}") })
end

+ (Object) clear_frame_managers(_pry_) Also known as: delete_frame_managers

Clear the stack of frame managers for the Pry instance

Parameters:

  • _pry_ (Pry)

    The Pry instance associated with the frame managers



93
94
95
96
# File 'lib/pry-stack_explorer.rb', line 93

def clear_frame_managers(_pry_)
  pop_frame_manager(_pry_) until frame_managers(_pry_).empty?
  frame_hash.delete(_pry_) # this line should be unnecessary!
end

+ (Object) create_and_push_frame_manager(bindings, _pry_, options = {})

Create a Pry::FrameManager object and push it onto the frame manager stack for the relevant _pry_ instance.

Parameters:

  • bindings (Array)

    The array of bindings (frames)

  • _pry_ (Pry)

    The Pry instance associated with the frame manager



35
36
37
38
39
40
# File 'lib/pry-stack_explorer.rb', line 35

def create_and_push_frame_manager(bindings, _pry_, options={})
  fm = FrameManager.new(bindings, _pry_)
  frame_hash[_pry_].push fm
  push_helper(fm, options)
  fm
end

+ (Hash) frame_hash

The hash storing all frames for all Pry instances for the current thread.

Returns:

  • (Hash)

    The hash storing all frames for all Pry instances for the current thread.



19
20
21
# File 'lib/pry-stack_explorer.rb', line 19

def frame_hash
  Thread.current[:__pry_frame_managers__] ||= Hash.new { |h, k| h[k] = [] }
end

+ (PryStackExplorer::FrameManager) frame_manager(_pry_)

The currently active frame manager

Returns:



101
102
103
# File 'lib/pry-stack_explorer.rb', line 101

def frame_manager(_pry_)
  frame_hash[_pry_].last
end

+ (Array) frame_managers(_pry_)

Return the complete frame manager stack for the Pry instance

Parameters:

  • _pry_ (Pry)

    The Pry instance associated with the frame managers

Returns:

  • (Array)

    The stack of Pry::FrameManager objections



27
28
29
# File 'lib/pry-stack_explorer.rb', line 27

def frame_managers(_pry_)
  frame_hash[_pry_]
end

+ (Pry::FrameManager) pop_frame_manager(_pry_)

Delete the currently active frame manager

Parameters:

  • _pry_ (Pry)

    The Pry instance associated with the frame managers.

Returns:

  • (Pry::FrameManager)

    The popped frame manager.



60
61
62
63
64
65
66
# File 'lib/pry-stack_explorer.rb', line 60

def pop_frame_manager(_pry_)
  return if frame_managers(_pry_).empty?

  popped_fm = frame_managers(_pry_).pop
  pop_helper(popped_fm, _pry_)
  popped_fm
end