pry-stack_explorer 0.2.5pre1 → 0.2.6pre1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -61,6 +61,12 @@ task :gems => [:clean, :rmgems, "ruby:gem"]
61
61
  desc "remove all platform gems"
62
62
  task :rmgems => ["ruby:clobber_package"]
63
63
 
64
+ desc "reinstall gem"
65
+ task :reinstall => :gems do
66
+ sh "gem uninstall pry-exception_explorer" rescue nil
67
+ sh "gem install #{direc}/pkg/#{PROJECT_NAME}-#{PryStackExplorer::VERSION}.gem"
68
+ end
69
+
64
70
  desc "build and push latest gems"
65
71
  task :pushgems => :gems do
66
72
  chdir("#{File.dirname(__FILE__)}/pkg") do
@@ -2,169 +2,52 @@
2
2
  # (C) John Mair (banisterfiend); MIT license
3
3
 
4
4
  require "pry-stack_explorer/version"
5
+ require "pry-stack_explorer/commands"
6
+ require "pry-stack_explorer/frame_manager"
5
7
  require "pry"
6
8
  require "binding_of_caller"
7
9
 
8
10
  module PryStackExplorer
11
+ Thread.current[:__pry_frame_managers__] ||= Hash.new { |h, k| h[k] = [] }
12
+
13
+ # Create a `Pry::FrameManager` object and push it onto the frame
14
+ # manager stack for the relevant `_pry_` instance.
15
+ # @param [Array] bindings The array of bindings (frames)
16
+ # @param [Pry] _pry_ The Pry instance associated with the frame manager
17
+ def self.push_and_create_frame_manager(bindings, _pry_)
18
+ Thread.current[:__pry_frame_managers__][_pry_].push FrameManager.new(bindings, _pry_)
19
+ end
9
20
 
10
- def self.add_frame_manager(bindings, _pry_)
11
- Thread.current[:__pry_frame_managers__] ||= {}
12
- Thread.current[:__pry_frame_managers__][_pry_] = FrameManager.new(bindings, _pry_)
21
+ # Delete the currently active frame manager
22
+ # @param [Pry] _pry_ The Pry instance associated with the frame managers
23
+ def self.pop_frame_manager(_pry_)
24
+ Thread.current[:__pry_frame_managers__][_pry_].pop
13
25
  end
14
26
 
15
- def self.delete_frame_manager(_pry_)
16
- Thread.current[:__pry_frame_managers__].delete(_pry_)
27
+ # Clear the stack of frame managers for the Pry instance
28
+ # @param [Pry] _pry_ The Pry instance associated with the frame managers
29
+ def self.clear_frame_managers(_pry_)
30
+ Thread.current[:__pry_frame_managers__][_pry_].clear
17
31
  end
18
32
 
33
+ # @return [PryStackExplorer::FrameManager] The currently active frame manager
19
34
  def self.frame_manager(_pry_)
20
- Thread.current[:__pry_frame_managers__][_pry_]
35
+ Thread.current[:__pry_frame_managers__][_pry_].last
21
36
  end
22
37
 
38
+ # Simple test to check whether two `Binding` objects are equal.
39
+ # @param [Binding] b1 First binding.
40
+ # @param [Binding] b2 Second binding.
23
41
  def self.bindings_equal?(b1, b2)
24
42
  (b1.eval('self') == b2.eval('self')) &&
25
43
  (b1.eval('__method__') == b2.eval('__method__')) &&
26
44
  (b1.eval('local_variables').map { |v| b1.eval("#{v}") } ==
27
45
  b2.eval('local_variables').map { |v| b2.eval("#{v}") })
28
46
  end
29
-
30
- class FrameManager
31
- attr_reader :binding_index
32
- attr_accessor :bindings
33
-
34
- def initialize(bindings, _pry_)
35
- @bindings = bindings
36
- @binding_index = 0
37
- @pry = _pry_
38
- end
39
-
40
- def convert_from_one_index(n)
41
- if n >= 0
42
- n - 1
43
- else
44
- n
45
- end
46
- end
47
- private :convert_from_one_index
48
-
49
- def signature(b)
50
- if b.eval('__method__')
51
- "#{closure_type} in #{b.eval('self').class}##{b.eval('__method__')}"
52
- else
53
- if b.eval('self').is_a?(Module)
54
- "#{closure_type} in <class:#{b.eval('self')}>"
55
- end
56
- end
57
- end
58
-
59
- def binding_info_for(b)
60
- b_self = b.eval('self')
61
- b_method = b.eval('__method__')
62
-
63
- if b_method && b_method != :__binding__ && b_method != :__binding_impl__
64
- b_method.to_s
65
- elsif b_self.instance_of?(Module)
66
- "<module:#{b_self}>"
67
- elsif b_self.instance_of?(Class)
68
- "<class:#{b_self}>"
69
- else
70
- "<main>"
71
- end
72
- end
73
-
74
- def change_binding_to(index)
75
- index = convert_from_one_index(index)
76
-
77
- if index > bindings.size - 1
78
- @pry.output.puts "Warning: At top of stack, cannot go further!"
79
- elsif index < 0
80
- @pry.output.puts "Warning: At bottom of stack, cannot go further!"
81
- else
82
- @binding_index = index
83
- @pry.binding_stack[-1] = bindings[binding_index]
84
-
85
- @pry.run_command "whereami"
86
- end
87
- end
88
- end
89
-
90
- StackCommands = Pry::CommandSet.new do
91
- command "up", "Go up to the caller's context" do |inc_str|
92
- inc = inc_str.nil? ? 1 : inc_str.to_i
93
-
94
- if !PryStackExplorer.frame_manager(_pry_)
95
- output.puts "Nowhere to go!"
96
- else
97
- binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
98
- PryStackExplorer.frame_manager(_pry_).change_binding_to binding_index + inc + 1
99
- end
100
- end
101
-
102
- command "down", "Go down to the callee's context." do |inc_str|
103
- inc = inc_str.nil? ? 1 : inc_str.to_i
104
-
105
- if !PryStackExplorer.frame_manager(_pry_)
106
- output.puts "Nowhere to go!"
107
- else
108
- binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
109
- PryStackExplorer.frame_manager(_pry_).change_binding_to binding_index - inc + 1
110
- end
111
- end
112
-
113
- command "show-stack", "Show all frames" do |*args|
114
- opts = parse_options!(args) do |opt|
115
- opt.banner unindent <<-USAGE
116
- Usage: show-stack [OPTIONS]
117
- Show all accessible stack frames.
118
- e.g: show-stack -v
119
- USAGE
120
-
121
- opt.on :v, :verbose, "Include extra information."
122
- end
123
-
124
- if !PryStackExplorer.frame_manager(_pry_)
125
- output.puts "No caller stack available!"
126
- else
127
- output.puts "\n#{text.bold('Showing all accessible frames in stack:')}\n--\n"
128
-
129
- PryStackExplorer.frame_manager(_pry_).bindings.each_with_index do |b, i|
130
- meth = b.eval('__method__')
131
- b_self = b.eval('self')
132
-
133
- desc = b.frame_description ? "#{text.bold('Description:')} #{b.frame_description}".ljust(40) :
134
- "#{text.bold('Description:')} #{PryStackExplorer.frame_manager(_pry_).binding_info_for(b)}".ljust(40)
135
- sig = meth ? "#{text.bold('Signature:')} #{Pry::Method.new(b_self.method(meth)).signature}".ljust(40) : "".ljust(32)
136
- type = b.frame_type ? "#{text.bold('Type:')} #{b.frame_type}".ljust(20) : "".ljust(20)
137
- slf = "#{text.bold('Self:')} #{b_self}".ljust(20)
138
- path = "#{text.bold("@ File:")} #{b.eval('__FILE__')}:#{b.eval('__LINE__')}"
139
-
140
- info = "##{i + 1} #{desc} #{sig} #{slf if opts[:v]} #{type \
141
- if opts[:v]} #{path if opts[:v]}"
142
- if i == PryStackExplorer.frame_manager(_pry_).binding_index
143
-
144
- output.puts "=> #{info}"
145
- else
146
- output.puts " #{info}"
147
- end
148
- end
149
- end
150
- end
151
-
152
- command "frame", "Switch to a particular frame." do |frame_num|
153
- if !PryStackExplorer.frame_manager(_pry_)
154
- output.puts "nowhere to go!"
155
- else
156
- PryStackExplorer.frame_manager(_pry_).change_binding_to frame_num.to_i
157
- end
158
- end
159
-
160
- command "frame-type", "Display current frame type." do
161
- output.puts _pry_.binding_stack.last.frame_type
162
- end
163
- end
164
47
  end
165
48
 
166
49
  Pry.config.hooks.add_hook(:after_session, :delete_frame_manager) do |_, _, _pry_|
167
- PryStackExplorer.delete_frame_manager(_pry_)
50
+ PryStackExplorer.clear_frame_managers(_pry_)
168
51
  end
169
52
 
170
53
  Pry.config.hooks.add_hook(:when_started, :save_caller_bindings) do |binding_stack, _pry_|
@@ -187,9 +70,10 @@ Pry.config.hooks.add_hook(:when_started, :save_caller_bindings) do |binding_stac
187
70
  end
188
71
 
189
72
  binding_stack.replace([bindings.first])
190
- PryStackExplorer.add_frame_manager(bindings, _pry_)
73
+ PryStackExplorer.push_and_create_frame_manager(bindings, _pry_)
191
74
  end
192
75
 
76
+ # Import the StackExplorer commands
193
77
  Pry.config.commands.import PryStackExplorer::StackCommands
194
78
 
195
79
  # monkey-patch the whereami command to show some frame information,
@@ -200,7 +84,7 @@ Pry.config.commands.before_command("whereami") do |num|
200
84
  binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
201
85
 
202
86
  output.puts "\n"
203
- output.puts "#{Pry::Helpers::Text.bold('Frame number:')} #{binding_index + 1}/#{bindings.size}"
87
+ output.puts "#{Pry::Helpers::Text.bold('Frame number:')} #{binding_index}/#{bindings.size - 1}"
204
88
  output.puts "#{Pry::Helpers::Text.bold('Frame type:')} #{bindings[binding_index].frame_type}" if bindings[binding_index].frame_type
205
89
  end
206
90
  end
@@ -0,0 +1,75 @@
1
+ module PryStackExplorer
2
+ StackCommands = Pry::CommandSet.new do
3
+ command "up", "Go up to the caller's context" do |inc_str|
4
+ inc = inc_str.nil? ? 1 : inc_str.to_i
5
+
6
+ if !PryStackExplorer.frame_manager(_pry_)
7
+ output.puts "Nowhere to go!"
8
+ else
9
+ binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
10
+ PryStackExplorer.frame_manager(_pry_).change_frame_to binding_index + inc
11
+ end
12
+ end
13
+
14
+ command "down", "Go down to the callee's context." do |inc_str|
15
+ inc = inc_str.nil? ? 1 : inc_str.to_i
16
+
17
+ if !PryStackExplorer.frame_manager(_pry_)
18
+ output.puts "Nowhere to go!"
19
+ else
20
+ binding_index = PryStackExplorer.frame_manager(_pry_).binding_index
21
+ PryStackExplorer.frame_manager(_pry_).change_frame_to binding_index - inc
22
+ end
23
+ end
24
+
25
+ command "show-stack", "Show all frames" do |*args|
26
+ opts = parse_options!(args) do |opt|
27
+ opt.banner unindent <<-USAGE
28
+ Usage: show-stack [OPTIONS]
29
+ Show all accessible stack frames.
30
+ e.g: show-stack -v
31
+ USAGE
32
+
33
+ opt.on :v, :verbose, "Include extra information."
34
+ end
35
+
36
+ if !PryStackExplorer.frame_manager(_pry_)
37
+ output.puts "No caller stack available!"
38
+ else
39
+ output.puts "\n#{text.bold('Showing all accessible frames in stack:')}\n--\n"
40
+
41
+ PryStackExplorer.frame_manager(_pry_).each_with_index do |b, i|
42
+ meth = b.eval('__method__')
43
+ b_self = b.eval('self')
44
+
45
+ desc = b.frame_description ? "#{text.bold('Description:')} #{b.frame_description}".ljust(40) :
46
+ "#{text.bold('Description:')} #{PryStackExplorer.frame_manager(_pry_).frame_info_for(b)}".ljust(40)
47
+ sig = meth ? "#{text.bold('Signature:')} #{Pry::Method.new(b_self.method(meth)).signature}".ljust(40) : "".ljust(32)
48
+ type = b.frame_type ? "#{text.bold('Type:')} #{b.frame_type}".ljust(20) : "".ljust(20)
49
+ slf_class = "#{text.bold('Self.class:')} #{b_self.class}".ljust(20)
50
+ path = "#{text.bold("@ File:")} #{b.eval('__FILE__')}:#{b.eval('__LINE__')}"
51
+
52
+ info = "##{i} #{desc} #{slf_class} #{sig} #{type \
53
+ if opts[:v]} #{path if opts[:v]}"
54
+ if i == PryStackExplorer.frame_manager(_pry_).binding_index
55
+ output.puts "=> #{info}"
56
+ else
57
+ output.puts " #{info}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ command "frame", "Switch to a particular frame." do |frame_num|
64
+ if !PryStackExplorer.frame_manager(_pry_)
65
+ output.puts "nowhere to go!"
66
+ else
67
+ PryStackExplorer.frame_manager(_pry_).change_frame_to frame_num.to_i
68
+ end
69
+ end
70
+
71
+ command "frame-type", "Display current frame type." do
72
+ output.puts _pry_.binding_stack.last.frame_type
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,80 @@
1
+ module PryStackExplorer
2
+
3
+ class FrameManager
4
+ include Enumerable
5
+
6
+ attr_accessor :binding_index
7
+ attr_accessor :bindings
8
+
9
+ # @return [Hash] A hash for user defined data
10
+ attr_reader :user
11
+
12
+ def initialize(bindings, _pry_)
13
+ self.bindings = bindings
14
+ self.binding_index = 0
15
+ @pry = _pry_
16
+ @user = {}
17
+ end
18
+
19
+ # Replace the current set of bindings (call stack) and binding
20
+ # index (current frame)
21
+ # @param [Array] bindings The new call stack (array of bindings)
22
+ # @param [Fixnum] binding_index The currently 'active' frame (binding).
23
+ def replace_call_stack(bindings, binding_index = 0)
24
+ self.bindings = bindings
25
+ self.binding_index = binding_index
26
+ end
27
+
28
+ # Iterate over all frames
29
+ def each(&block)
30
+ bindings.each(&block)
31
+ end
32
+
33
+ # Return a description of the frame (binding)
34
+ # @param [Binding] b The binding.
35
+ # @return [String] A description of the frame (binding).
36
+ def frame_info_for(b)
37
+ b_self = b.eval('self')
38
+ b_method = b.eval('__method__')
39
+
40
+ if b_method && b_method != :__binding__ && b_method != :__binding_impl__
41
+ b_method.to_s
42
+ elsif b_self.instance_of?(Module)
43
+ "<module:#{b_self}>"
44
+ elsif b_self.instance_of?(Class)
45
+ "<class:#{b_self}>"
46
+ else
47
+ "<main>"
48
+ end
49
+ end
50
+
51
+ # Ensure the Pry instance's active binding is the frame manager's
52
+ # active binding.
53
+ def refresh_frame
54
+ change_frame_to binding_index
55
+ end
56
+
57
+ # @return [Binding] The currently active frame
58
+ def current_frame
59
+ bindings[binding_index]
60
+ end
61
+
62
+ # Change active frame to the one indexed by `index`.
63
+ # Note that indexing base is `0`
64
+ # @param [Fixnum] index The index of the frame.
65
+ def change_frame_to(index)
66
+
67
+ if index > bindings.size - 1
68
+ @pry.output.puts "Warning: At top of stack, cannot go further!"
69
+ elsif index < 0
70
+ @pry.output.puts "Warning: At bottom of stack, cannot go further!"
71
+ else
72
+ self.binding_index = index
73
+ @pry.binding_stack[-1] = bindings[binding_index]
74
+
75
+ @pry.run_command "whereami"
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -1,3 +1,3 @@
1
1
  module PryStackExplorer
2
- VERSION = "0.2.5pre1"
2
+ VERSION = "0.2.6pre1"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: pry-stack_explorer
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 5
5
- version: 0.2.5pre1
5
+ version: 0.2.6pre1
6
6
  platform: ruby
7
7
  authors:
8
8
  - John Mair (banisterfiend)
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-12-06 00:00:00 Z
13
+ date: 2011-12-15 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: binding_of_caller
@@ -43,6 +43,8 @@ extensions: []
43
43
  extra_rdoc_files: []
44
44
 
45
45
  files:
46
+ - lib/pry-stack_explorer/commands.rb
47
+ - lib/pry-stack_explorer/frame_manager.rb
46
48
  - lib/pry-stack_explorer/version.rb
47
49
  - lib/pry-stack_explorer.rb
48
50
  - test/test.rb