pry 0.6.7pre4-i386-mingw32 → 0.6.8-i386-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +88 -75
- data/LICENSE +25 -25
- data/README.markdown +321 -309
- data/Rakefile +103 -103
- data/bin/pry +83 -82
- data/examples/example_basic.rb +17 -17
- data/examples/example_command_override.rb +35 -35
- data/examples/example_commands.rb +39 -39
- data/examples/example_hooks.rb +12 -12
- data/examples/example_image_edit.rb +71 -71
- data/examples/example_input.rb +10 -10
- data/examples/example_input2.rb +32 -32
- data/examples/example_output.rb +14 -14
- data/examples/example_print.rb +9 -9
- data/examples/example_prompt.rb +12 -12
- data/lib/pry.rb +32 -32
- data/lib/pry/command_base.rb +150 -150
- data/lib/pry/commands.rb +616 -577
- data/lib/pry/completion.rb +202 -202
- data/lib/pry/core_extensions.rb +55 -55
- data/lib/pry/hooks.rb +19 -8
- data/lib/pry/print.rb +19 -19
- data/lib/pry/prompts.rb +26 -26
- data/lib/pry/pry_class.rb +219 -186
- data/lib/pry/pry_instance.rb +316 -316
- data/lib/pry/version.rb +3 -3
- data/test/test.rb +725 -681
- data/test/test_helper.rb +46 -38
- data/test/testrc +2 -0
- metadata +102 -66
data/lib/pry/command_base.rb
CHANGED
@@ -1,150 +1,150 @@
|
|
1
|
-
class Pry
|
2
|
-
|
3
|
-
# Basic command functionality. All user-defined commands must
|
4
|
-
# inherit from this class. It provides the `command` method.
|
5
|
-
class CommandBase
|
6
|
-
class << self
|
7
|
-
attr_accessor :commands
|
8
|
-
attr_accessor :opts, :output, :target
|
9
|
-
|
10
|
-
# private because we want to force function style invocation. We require
|
11
|
-
# that the location where the block is defined has the `opts`
|
12
|
-
# method in scope.
|
13
|
-
private
|
14
|
-
|
15
|
-
# Defines a new Pry command.
|
16
|
-
# @param [String, Array] names The name of the command (or array of
|
17
|
-
# command name aliases).
|
18
|
-
# @param [String] description A description of the command.
|
19
|
-
# @param [Hash] options The optional configuration parameters.
|
20
|
-
# @option options [Boolean] :keep_retval Whether or not to use return value
|
21
|
-
# of the block for return of `command` or just to return `nil`
|
22
|
-
# (the default).
|
23
|
-
# @yield The action to perform. The parameters in the block
|
24
|
-
# determines the parameters the command will receive. All
|
25
|
-
# parameters passed into the block will be strings. Successive
|
26
|
-
# command parameters are separated by whitespace at the Pry prompt.
|
27
|
-
# @example
|
28
|
-
# class MyCommands < Pry::CommandBase
|
29
|
-
# command "greet", "Greet somebody" do |name|
|
30
|
-
# puts "Good afternoon #{name.capitalize}!"
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# # From pry:
|
35
|
-
# # pry(main)> _pry_.commands = MyCommands
|
36
|
-
# # pry(main)> greet john
|
37
|
-
# # Good afternoon John!
|
38
|
-
# # pry(main)> help greet
|
39
|
-
# # Greet somebody
|
40
|
-
def command(names, description="No description.", options={}, &block)
|
41
|
-
options = {
|
42
|
-
:keep_retval => false
|
43
|
-
}.merge!(options)
|
44
|
-
|
45
|
-
@commands ||= {}
|
46
|
-
|
47
|
-
Array(names).each do |name|
|
48
|
-
commands[name] = {
|
49
|
-
:description => description,
|
50
|
-
:action => block,
|
51
|
-
:keep_retval => options[:keep_retval]
|
52
|
-
}
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Delete a command or an array of commands.
|
57
|
-
# Useful when inheriting from another command set and pruning
|
58
|
-
# those commands down to the ones you want.
|
59
|
-
# @param [Array<String>] names The command name or array
|
60
|
-
# of command names you want to delete
|
61
|
-
# @example Deleteing inherited commands
|
62
|
-
# class MyCommands < Pry::Commands
|
63
|
-
# delete "show_method", "show_imethod", "show_doc", "show_idoc"
|
64
|
-
# end
|
65
|
-
# Pry.commands = MyCommands
|
66
|
-
def delete(*names)
|
67
|
-
names.each { |name| commands.delete(name) }
|
68
|
-
end
|
69
|
-
|
70
|
-
# Execute a command (this enables commands to call other commands).
|
71
|
-
# @param [String] name The command to execute
|
72
|
-
# @param [Array] args The parameters to pass to the command.
|
73
|
-
# @example Wrap one command with another
|
74
|
-
# class MyCommands < Pry::Commands
|
75
|
-
# command "ls2" do
|
76
|
-
# output.puts "before ls"
|
77
|
-
# run "ls"
|
78
|
-
# output.puts "after ls"
|
79
|
-
# end
|
80
|
-
# end
|
81
|
-
def run(name, *args)
|
82
|
-
action = opts[:commands][name][:action]
|
83
|
-
instance_exec(*args, &action)
|
84
|
-
end
|
85
|
-
|
86
|
-
# Import commands from another command object.
|
87
|
-
# @param [Pry::CommandBase] klass The class to import from (must
|
88
|
-
# be a subclass of `Pry::CommandBase`)
|
89
|
-
# @param [Array<String>] names The commands to import.
|
90
|
-
# @example
|
91
|
-
# class MyCommands < Pry::CommandBase
|
92
|
-
# import_from Pry::Commands, "ls", "show_method", "cd"
|
93
|
-
# end
|
94
|
-
def import_from(klass, *names)
|
95
|
-
imported_hash = Hash[klass.commands.select { |k, v| names.include?(k) }]
|
96
|
-
commands.merge!(imported_hash)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Create an alias for a command.
|
100
|
-
# @param [String] new_command The alias name.
|
101
|
-
# @param [String] orig_command The original command name.
|
102
|
-
# @param [String] desc The optional description.
|
103
|
-
# @example
|
104
|
-
# class MyCommands < Pry::CommandBase
|
105
|
-
# alias_command "help_alias", "help"
|
106
|
-
# end
|
107
|
-
def alias_command(new_command_name, orig_command_name, desc=nil)
|
108
|
-
commands[new_command_name] = commands[orig_command_name].dup
|
109
|
-
commands[new_command_name][:description] = desc if desc
|
110
|
-
end
|
111
|
-
|
112
|
-
# Set the description for a command (replacing the old
|
113
|
-
# description.)
|
114
|
-
# @param [String] name The command name.
|
115
|
-
# @param [String] description The command description.
|
116
|
-
# @example
|
117
|
-
# class MyCommands < Pry::CommandBase
|
118
|
-
# desc "help", "help description"
|
119
|
-
# end
|
120
|
-
def desc(name, description)
|
121
|
-
commands[name][:description] = description
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
command "help", "This menu." do |cmd|
|
126
|
-
command_info = opts[:commands]
|
127
|
-
param = cmd
|
128
|
-
|
129
|
-
if !param
|
130
|
-
output.puts "Command list:"
|
131
|
-
output.puts "--"
|
132
|
-
command_info.each do |k, data|
|
133
|
-
output.puts "#{k}".ljust(18) + data[:description] if !data[:description].empty?
|
134
|
-
end
|
135
|
-
else
|
136
|
-
if command_info[param]
|
137
|
-
output.puts command_info[param][:description]
|
138
|
-
else
|
139
|
-
output.puts "No info for command: #{param}"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Ensures that commands can be inherited
|
145
|
-
def self.inherited(klass)
|
146
|
-
klass.commands = commands.dup
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
150
|
-
end
|
1
|
+
class Pry
|
2
|
+
|
3
|
+
# Basic command functionality. All user-defined commands must
|
4
|
+
# inherit from this class. It provides the `command` method.
|
5
|
+
class CommandBase
|
6
|
+
class << self
|
7
|
+
attr_accessor :commands
|
8
|
+
attr_accessor :opts, :output, :target
|
9
|
+
|
10
|
+
# private because we want to force function style invocation. We require
|
11
|
+
# that the location where the block is defined has the `opts`
|
12
|
+
# method in scope.
|
13
|
+
private
|
14
|
+
|
15
|
+
# Defines a new Pry command.
|
16
|
+
# @param [String, Array] names The name of the command (or array of
|
17
|
+
# command name aliases).
|
18
|
+
# @param [String] description A description of the command.
|
19
|
+
# @param [Hash] options The optional configuration parameters.
|
20
|
+
# @option options [Boolean] :keep_retval Whether or not to use return value
|
21
|
+
# of the block for return of `command` or just to return `nil`
|
22
|
+
# (the default).
|
23
|
+
# @yield The action to perform. The parameters in the block
|
24
|
+
# determines the parameters the command will receive. All
|
25
|
+
# parameters passed into the block will be strings. Successive
|
26
|
+
# command parameters are separated by whitespace at the Pry prompt.
|
27
|
+
# @example
|
28
|
+
# class MyCommands < Pry::CommandBase
|
29
|
+
# command "greet", "Greet somebody" do |name|
|
30
|
+
# puts "Good afternoon #{name.capitalize}!"
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# # From pry:
|
35
|
+
# # pry(main)> _pry_.commands = MyCommands
|
36
|
+
# # pry(main)> greet john
|
37
|
+
# # Good afternoon John!
|
38
|
+
# # pry(main)> help greet
|
39
|
+
# # Greet somebody
|
40
|
+
def command(names, description="No description.", options={}, &block)
|
41
|
+
options = {
|
42
|
+
:keep_retval => false
|
43
|
+
}.merge!(options)
|
44
|
+
|
45
|
+
@commands ||= {}
|
46
|
+
|
47
|
+
Array(names).each do |name|
|
48
|
+
commands[name] = {
|
49
|
+
:description => description,
|
50
|
+
:action => block,
|
51
|
+
:keep_retval => options[:keep_retval]
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Delete a command or an array of commands.
|
57
|
+
# Useful when inheriting from another command set and pruning
|
58
|
+
# those commands down to the ones you want.
|
59
|
+
# @param [Array<String>] names The command name or array
|
60
|
+
# of command names you want to delete
|
61
|
+
# @example Deleteing inherited commands
|
62
|
+
# class MyCommands < Pry::Commands
|
63
|
+
# delete "show_method", "show_imethod", "show_doc", "show_idoc"
|
64
|
+
# end
|
65
|
+
# Pry.commands = MyCommands
|
66
|
+
def delete(*names)
|
67
|
+
names.each { |name| commands.delete(name) }
|
68
|
+
end
|
69
|
+
|
70
|
+
# Execute a command (this enables commands to call other commands).
|
71
|
+
# @param [String] name The command to execute
|
72
|
+
# @param [Array] args The parameters to pass to the command.
|
73
|
+
# @example Wrap one command with another
|
74
|
+
# class MyCommands < Pry::Commands
|
75
|
+
# command "ls2" do
|
76
|
+
# output.puts "before ls"
|
77
|
+
# run "ls"
|
78
|
+
# output.puts "after ls"
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
def run(name, *args)
|
82
|
+
action = opts[:commands][name][:action]
|
83
|
+
instance_exec(*args, &action)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Import commands from another command object.
|
87
|
+
# @param [Pry::CommandBase] klass The class to import from (must
|
88
|
+
# be a subclass of `Pry::CommandBase`)
|
89
|
+
# @param [Array<String>] names The commands to import.
|
90
|
+
# @example
|
91
|
+
# class MyCommands < Pry::CommandBase
|
92
|
+
# import_from Pry::Commands, "ls", "show_method", "cd"
|
93
|
+
# end
|
94
|
+
def import_from(klass, *names)
|
95
|
+
imported_hash = Hash[klass.commands.select { |k, v| names.include?(k) }]
|
96
|
+
commands.merge!(imported_hash)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Create an alias for a command.
|
100
|
+
# @param [String] new_command The alias name.
|
101
|
+
# @param [String] orig_command The original command name.
|
102
|
+
# @param [String] desc The optional description.
|
103
|
+
# @example
|
104
|
+
# class MyCommands < Pry::CommandBase
|
105
|
+
# alias_command "help_alias", "help"
|
106
|
+
# end
|
107
|
+
def alias_command(new_command_name, orig_command_name, desc=nil)
|
108
|
+
commands[new_command_name] = commands[orig_command_name].dup
|
109
|
+
commands[new_command_name][:description] = desc if desc
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set the description for a command (replacing the old
|
113
|
+
# description.)
|
114
|
+
# @param [String] name The command name.
|
115
|
+
# @param [String] description The command description.
|
116
|
+
# @example
|
117
|
+
# class MyCommands < Pry::CommandBase
|
118
|
+
# desc "help", "help description"
|
119
|
+
# end
|
120
|
+
def desc(name, description)
|
121
|
+
commands[name][:description] = description
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
command "help", "This menu." do |cmd|
|
126
|
+
command_info = opts[:commands]
|
127
|
+
param = cmd
|
128
|
+
|
129
|
+
if !param
|
130
|
+
output.puts "Command list:"
|
131
|
+
output.puts "--"
|
132
|
+
command_info.each do |k, data|
|
133
|
+
output.puts "#{k}".ljust(18) + data[:description] if !data[:description].empty?
|
134
|
+
end
|
135
|
+
else
|
136
|
+
if command_info[param]
|
137
|
+
output.puts command_info[param][:description]
|
138
|
+
else
|
139
|
+
output.puts "No info for command: #{param}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Ensures that commands can be inherited
|
145
|
+
def self.inherited(klass)
|
146
|
+
klass.commands = commands.dup
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
data/lib/pry/commands.rb
CHANGED
@@ -1,577 +1,616 @@
|
|
1
|
-
require "optparse"
|
2
|
-
require "method_source"
|
3
|
-
require "pry/command_base"
|
4
|
-
require "pry/pry_instance"
|
5
|
-
|
6
|
-
class Pry
|
7
|
-
|
8
|
-
# Default commands used by Pry.
|
9
|
-
class Commands < CommandBase
|
10
|
-
|
11
|
-
# We make this a lambda to avoid documenting it
|
12
|
-
meth_name_from_binding = lambda do |b|
|
13
|
-
meth_name = b.eval('__method__')
|
14
|
-
if [nil, :__binding__, :__binding_impl__].include?(meth_name)
|
15
|
-
nil
|
16
|
-
else
|
17
|
-
meth_name
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
check_for_dynamically_defined_method = lambda do |file|
|
22
|
-
if file =~ /(\(.*\))|<.*>/
|
23
|
-
raise "Cannot retrieve source for dynamically defined method."
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
remove_first_word = lambda do |text|
|
28
|
-
text.split.drop(1).join(' ')
|
29
|
-
end
|
30
|
-
|
31
|
-
command "
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
command "
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
output.puts "
|
88
|
-
end
|
89
|
-
|
90
|
-
command "
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
if
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
#
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
options
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
end
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
end
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
if
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
if
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
end
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
if
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
end
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
1
|
+
require "optparse"
|
2
|
+
require "method_source"
|
3
|
+
require "pry/command_base"
|
4
|
+
require "pry/pry_instance"
|
5
|
+
|
6
|
+
class Pry
|
7
|
+
|
8
|
+
# Default commands used by Pry.
|
9
|
+
class Commands < CommandBase
|
10
|
+
|
11
|
+
# We make this a lambda to avoid documenting it
|
12
|
+
meth_name_from_binding = lambda do |b|
|
13
|
+
meth_name = b.eval('__method__')
|
14
|
+
if [nil, :__binding__, :__binding_impl__].include?(meth_name)
|
15
|
+
nil
|
16
|
+
else
|
17
|
+
meth_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
check_for_dynamically_defined_method = lambda do |file|
|
22
|
+
if file =~ /(\(.*\))|<.*>/
|
23
|
+
raise "Cannot retrieve source for dynamically defined method."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
remove_first_word = lambda do |text|
|
28
|
+
text.split.drop(1).join(' ')
|
29
|
+
end
|
30
|
+
|
31
|
+
command "whereami", "Show the code context for the session." do
|
32
|
+
file = target.eval('__FILE__')
|
33
|
+
line_num = target.eval('__LINE__')
|
34
|
+
klass = target.eval('self.class')
|
35
|
+
|
36
|
+
meth_name = meth_name_from_binding.call(target)
|
37
|
+
if !meth_name
|
38
|
+
output.puts "Cannot find containing method. Did you remember to use \`binding.pry\` ?"
|
39
|
+
next
|
40
|
+
end
|
41
|
+
|
42
|
+
check_for_dynamically_defined_method.call(file)
|
43
|
+
|
44
|
+
output.puts "--\nFrom #{file} @ line #{line_num} in #{klass}##{meth_name}:\n--"
|
45
|
+
|
46
|
+
# This method inspired by http://rubygems.org/gems/ir_b
|
47
|
+
File.open(file).each_with_index do |line, index|
|
48
|
+
line_n = index + 1
|
49
|
+
next unless line_n > (line_num - 6)
|
50
|
+
break if line_n > (line_num + 5)
|
51
|
+
if line_n == line_num
|
52
|
+
code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
|
53
|
+
if Pry.color
|
54
|
+
code = CodeRay.scan(code, :ruby).term
|
55
|
+
end
|
56
|
+
output.puts code
|
57
|
+
code
|
58
|
+
else
|
59
|
+
code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
|
60
|
+
if Pry.color
|
61
|
+
code = CodeRay.scan(code, :ruby).term
|
62
|
+
end
|
63
|
+
output.puts code
|
64
|
+
code
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
|
70
|
+
output.puts "Input buffer cleared!"
|
71
|
+
opts[:eval_string].clear
|
72
|
+
end
|
73
|
+
|
74
|
+
command "!pry", "Start a Pry session on current self; this even works mid-expression." do
|
75
|
+
Pry.start(target)
|
76
|
+
end
|
77
|
+
|
78
|
+
command "exit-program", "End the current program. Aliases: quit-program, !!!" do
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
|
82
|
+
alias_command "quit-program", "exit-program", ""
|
83
|
+
alias_command "!!!", "exit-program", ""
|
84
|
+
|
85
|
+
command "toggle-color", "Toggle syntax highlighting." do
|
86
|
+
Pry.color = !Pry.color
|
87
|
+
output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
|
88
|
+
end
|
89
|
+
|
90
|
+
command "simple-prompt", "Toggle the simple prompt." do
|
91
|
+
case Pry.active_instance.prompt
|
92
|
+
when Pry::SIMPLE_PROMPT
|
93
|
+
Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
|
94
|
+
else
|
95
|
+
Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
command "nesting", "Show nesting information." do
|
100
|
+
nesting = opts[:nesting]
|
101
|
+
|
102
|
+
output.puts "Nesting status:"
|
103
|
+
output.puts "--"
|
104
|
+
nesting.each do |level, obj|
|
105
|
+
if level == 0
|
106
|
+
output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
|
107
|
+
else
|
108
|
+
output.puts "#{level}. #{Pry.view_clip(obj)}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
command "status", "Show status information." do
|
114
|
+
nesting = opts[:nesting]
|
115
|
+
|
116
|
+
output.puts "Status:"
|
117
|
+
output.puts "--"
|
118
|
+
output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
|
119
|
+
output.puts "Nesting level: #{nesting.level}"
|
120
|
+
output.puts "Pry version: #{Pry::VERSION}"
|
121
|
+
output.puts "Ruby version: #{RUBY_VERSION}"
|
122
|
+
|
123
|
+
mn = meth_name_from_binding.call(target)
|
124
|
+
output.puts "Current method: #{mn ? mn : "N/A"}"
|
125
|
+
output.puts "Pry instance: #{Pry.active_instance}"
|
126
|
+
output.puts "Last result: #{Pry.view(Pry.last_result)}"
|
127
|
+
end
|
128
|
+
|
129
|
+
command "version", "Show Pry version." do
|
130
|
+
output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
|
131
|
+
end
|
132
|
+
|
133
|
+
command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
|
134
|
+
str = remove_first_word.call(opts[:val])
|
135
|
+
throw(:breakout, [0, target.eval(str)])
|
136
|
+
end
|
137
|
+
|
138
|
+
alias_command "!@", "exit-all", ""
|
139
|
+
|
140
|
+
command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
|
141
|
+
options = {}
|
142
|
+
|
143
|
+
# Set target local to the default -- note that we can set a different target for
|
144
|
+
# ls if we like: e.g ls my_var
|
145
|
+
target = target()
|
146
|
+
|
147
|
+
OptionParser.new do |opts|
|
148
|
+
opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
|
149
|
+
List information about VAR (the current context by default).
|
150
|
+
Shows local and instance variables by default.
|
151
|
+
--
|
152
|
+
}
|
153
|
+
opts.on("-g", "--globals", "Display global variables.") do
|
154
|
+
options[:g] = true
|
155
|
+
end
|
156
|
+
|
157
|
+
opts.on("-c", "--constants", "Display constants.") do
|
158
|
+
options[:c] = true
|
159
|
+
end
|
160
|
+
|
161
|
+
opts.on("-l", "--locals", "Display locals.") do
|
162
|
+
options[:l] = true
|
163
|
+
end
|
164
|
+
|
165
|
+
opts.on("-i", "--ivars", "Display instance variables.") do
|
166
|
+
options[:i] = true
|
167
|
+
end
|
168
|
+
|
169
|
+
opts.on("-k", "--class-vars", "Display class variables.") do
|
170
|
+
options[:k] = true
|
171
|
+
end
|
172
|
+
|
173
|
+
opts.on("-m", "--methods", "Display methods (public methods by default).") do
|
174
|
+
options[:m] = true
|
175
|
+
end
|
176
|
+
|
177
|
+
opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
|
178
|
+
options[:M] = true
|
179
|
+
end
|
180
|
+
|
181
|
+
opts.on("-P", "--public", "Display public methods (with -m).") do
|
182
|
+
options[:P] = true
|
183
|
+
end
|
184
|
+
|
185
|
+
opts.on("-r", "--protected", "Display protected methods (with -m).") do
|
186
|
+
options[:r] = true
|
187
|
+
end
|
188
|
+
|
189
|
+
opts.on("-p", "--private", "Display private methods (with -m).") do
|
190
|
+
options[:p] = true
|
191
|
+
end
|
192
|
+
|
193
|
+
opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
|
194
|
+
options[:s] = true
|
195
|
+
end
|
196
|
+
|
197
|
+
opts.on("-a", "--all", "Display all types of entries.") do
|
198
|
+
options[:a] = true
|
199
|
+
end
|
200
|
+
|
201
|
+
opts.on("-v", "--verbose", "Verbose ouput.") do
|
202
|
+
options[:v] = true
|
203
|
+
end
|
204
|
+
|
205
|
+
opts.on_tail("-h", "--help", "Show this message.") do
|
206
|
+
output.puts opts
|
207
|
+
options[:h] = true
|
208
|
+
end
|
209
|
+
end.order(args) do |new_target|
|
210
|
+
target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
|
211
|
+
end
|
212
|
+
|
213
|
+
# exit if we've displayed help
|
214
|
+
next if options[:h]
|
215
|
+
|
216
|
+
# default is locals/ivars/class vars.
|
217
|
+
# Only occurs when no options or when only option is verbose
|
218
|
+
options.merge!({
|
219
|
+
:l => true,
|
220
|
+
:i => true,
|
221
|
+
:k => true
|
222
|
+
}) if options.empty? || (options.size == 1 && options[:v])
|
223
|
+
|
224
|
+
# Display public methods by default if -m or -M switch is used.
|
225
|
+
options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r])
|
226
|
+
|
227
|
+
info = {}
|
228
|
+
target_self = target.eval('self')
|
229
|
+
|
230
|
+
# ensure we have a real boolean and not a `nil` (important when
|
231
|
+
# interpolating in the string)
|
232
|
+
options[:s] = !!options[:s]
|
233
|
+
|
234
|
+
# Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
|
235
|
+
i = -1
|
236
|
+
|
237
|
+
# Start collecting the entries selected by the user
|
238
|
+
info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
|
239
|
+
info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
|
240
|
+
|
241
|
+
info["class variables"] = [if target_self.is_a?(Module)
|
242
|
+
Array(target.eval("class_variables")).sort
|
243
|
+
else
|
244
|
+
Array(target.eval("self.class.class_variables")).sort
|
245
|
+
end, i += 1] if options[:k] || options[:a]
|
246
|
+
|
247
|
+
info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
|
248
|
+
|
249
|
+
info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
|
250
|
+
|
251
|
+
info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
|
252
|
+
|
253
|
+
info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
|
254
|
+
|
255
|
+
info["public instance methods"] = [Array(target.eval("public_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:P]) || options[:a])
|
256
|
+
|
257
|
+
info["protected instance methods"] = [Array(target.eval("protected_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:r]) || options[:a])
|
258
|
+
|
259
|
+
info["private instance methods"] = [Array(target.eval("private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:p]) || options[:a])
|
260
|
+
|
261
|
+
# dealing with 1.8/1.9 compatibility issues :/
|
262
|
+
csuper = options[:s]
|
263
|
+
if Module.method(:constants).arity == 0
|
264
|
+
csuper = nil
|
265
|
+
end
|
266
|
+
|
267
|
+
info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
|
268
|
+
target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
|
269
|
+
|
270
|
+
# verbose output?
|
271
|
+
if options[:v]
|
272
|
+
|
273
|
+
# verbose
|
274
|
+
info.sort_by { |k, v| v.last }.each do |k, v|
|
275
|
+
if !v.first.empty?
|
276
|
+
output.puts "#{k}:\n--"
|
277
|
+
if Pry.color
|
278
|
+
output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
|
279
|
+
else
|
280
|
+
output.puts Pry.view(v.first)
|
281
|
+
end
|
282
|
+
output.puts
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
# plain
|
287
|
+
else
|
288
|
+
list = info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+)
|
289
|
+
if Pry.color
|
290
|
+
output.puts CodeRay.scan(Pry.view(list), :ruby).term
|
291
|
+
else
|
292
|
+
output.puts Pry.view(list)
|
293
|
+
end
|
294
|
+
list
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
command "cat-file", "Show output of file FILE" do |file_name|
|
299
|
+
if !file_name
|
300
|
+
output.puts "Must provide a file name."
|
301
|
+
next
|
302
|
+
end
|
303
|
+
|
304
|
+
contents = File.read(File.expand_path(file_name))
|
305
|
+
output.puts contents
|
306
|
+
contents
|
307
|
+
end
|
308
|
+
|
309
|
+
command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
|
310
|
+
options = {}
|
311
|
+
target = target()
|
312
|
+
file_name = nil
|
313
|
+
|
314
|
+
OptionParser.new do |opts|
|
315
|
+
opts.banner = %{Usage: eval-file [OPTIONS] FILE
|
316
|
+
Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
|
317
|
+
e.g: eval-file -c self "hello.rb"
|
318
|
+
--
|
319
|
+
}
|
320
|
+
opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
|
321
|
+
options[:c] = true
|
322
|
+
target = Pry.binding_for(target.eval(context))
|
323
|
+
end
|
324
|
+
|
325
|
+
opts.on_tail("-h", "--help", "This message.") do
|
326
|
+
output.puts opts
|
327
|
+
options[:h] = true
|
328
|
+
end
|
329
|
+
end.order(args) do |v|
|
330
|
+
file_name = v
|
331
|
+
end
|
332
|
+
|
333
|
+
next if options[:h]
|
334
|
+
|
335
|
+
if !file_name
|
336
|
+
output.puts "You need to specify a file name. Type `eval-file --help` for help"
|
337
|
+
next
|
338
|
+
end
|
339
|
+
|
340
|
+
old_constants = Object.constants
|
341
|
+
if options[:c]
|
342
|
+
target_self = target.eval('self')
|
343
|
+
target.eval(File.read(File.expand_path(file_name)))
|
344
|
+
output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
|
345
|
+
else
|
346
|
+
TOPLEVEL_BINDING.eval(File.read(File.expand_path(file_name)))
|
347
|
+
output.puts "--\nEval'd '#{file_name}' at top-level."
|
348
|
+
end
|
349
|
+
new_constants = Object.constants - old_constants
|
350
|
+
output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
|
351
|
+
end
|
352
|
+
|
353
|
+
command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
|
354
|
+
if !obj
|
355
|
+
output.puts "Must provide an object to inspect."
|
356
|
+
next
|
357
|
+
end
|
358
|
+
|
359
|
+
output.puts Pry.view(target.eval("#{obj}"))
|
360
|
+
end
|
361
|
+
|
362
|
+
alias_command "inspect", "cat", ""
|
363
|
+
|
364
|
+
command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
|
365
|
+
if !obj
|
366
|
+
output.puts "Must provide an object."
|
367
|
+
next
|
368
|
+
end
|
369
|
+
|
370
|
+
throw(:breakout, opts[:nesting].level) if obj == ".."
|
371
|
+
|
372
|
+
if obj == "/"
|
373
|
+
throw(:breakout, 1) if opts[:nesting].level > 0
|
374
|
+
next
|
375
|
+
end
|
376
|
+
|
377
|
+
target.eval("#{obj}.pry")
|
378
|
+
end
|
379
|
+
|
380
|
+
command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
|
381
|
+
options = {}
|
382
|
+
target = target()
|
383
|
+
meth_name = nil
|
384
|
+
|
385
|
+
OptionParser.new do |opts|
|
386
|
+
opts.banner = %{Usage: show-doc [OPTIONS] [METH]
|
387
|
+
Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
|
388
|
+
e.g show-doc hello_method
|
389
|
+
--
|
390
|
+
}
|
391
|
+
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
392
|
+
options[:M] = true
|
393
|
+
end
|
394
|
+
|
395
|
+
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
396
|
+
target = Pry.binding_for(target.eval(context))
|
397
|
+
end
|
398
|
+
|
399
|
+
opts.on_tail("-h", "--help", "This message.") do
|
400
|
+
output.puts opts
|
401
|
+
options[:h] = true
|
402
|
+
end
|
403
|
+
end.order(args) do |v|
|
404
|
+
meth_name = v
|
405
|
+
end
|
406
|
+
|
407
|
+
next if options[:h]
|
408
|
+
|
409
|
+
if !meth_name
|
410
|
+
output.puts "You need to specify a method. Type `show-doc --help` for help"
|
411
|
+
next
|
412
|
+
end
|
413
|
+
|
414
|
+
begin
|
415
|
+
if options[:M]
|
416
|
+
meth = target.eval("instance_method(:#{meth_name})")
|
417
|
+
else
|
418
|
+
meth = target.eval("method(:#{meth_name})")
|
419
|
+
end
|
420
|
+
rescue
|
421
|
+
output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
|
422
|
+
next
|
423
|
+
end
|
424
|
+
|
425
|
+
doc = meth.comment
|
426
|
+
file, line = meth.source_location
|
427
|
+
check_for_dynamically_defined_method.call(file)
|
428
|
+
|
429
|
+
output.puts "--\nFrom #{file} @ line ~#{line}:\n--"
|
430
|
+
|
431
|
+
if Pry.color
|
432
|
+
doc = CodeRay.scan(doc, :ruby).term
|
433
|
+
end
|
434
|
+
|
435
|
+
output.puts doc
|
436
|
+
doc
|
437
|
+
end
|
438
|
+
|
439
|
+
command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
|
440
|
+
options = {}
|
441
|
+
target = target()
|
442
|
+
meth_name = nil
|
443
|
+
|
444
|
+
OptionParser.new do |opts|
|
445
|
+
opts.banner = %{Usage: show-method [OPTIONS] [METH]
|
446
|
+
Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
|
447
|
+
e.g: show-method hello_method
|
448
|
+
--
|
449
|
+
}
|
450
|
+
opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
|
451
|
+
options[:M] = true
|
452
|
+
end
|
453
|
+
|
454
|
+
opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
|
455
|
+
target = Pry.binding_for(target.eval(context))
|
456
|
+
end
|
457
|
+
|
458
|
+
opts.on_tail("-h", "--help", "This message.") do
|
459
|
+
output.puts opts
|
460
|
+
options[:h] = true
|
461
|
+
end
|
462
|
+
end.order(args) do |v|
|
463
|
+
meth_name = v
|
464
|
+
end
|
465
|
+
|
466
|
+
next if options[:h]
|
467
|
+
|
468
|
+
# If no method name is given then use current method, if it exists
|
469
|
+
meth_name = meth_name_from_binding.call(target) if !meth_name
|
470
|
+
|
471
|
+
if !meth_name
|
472
|
+
output.puts "You need to specify a method. Type `show-method --help` for help"
|
473
|
+
next
|
474
|
+
end
|
475
|
+
|
476
|
+
begin
|
477
|
+
if options[:M]
|
478
|
+
meth = target.eval("instance_method(:#{meth_name})")
|
479
|
+
else
|
480
|
+
meth = target.eval("method(:#{meth_name})")
|
481
|
+
end
|
482
|
+
rescue
|
483
|
+
target_self = target.eval('self')
|
484
|
+
if !options[:M]&& target_self.is_a?(Module) &&
|
485
|
+
target_self.method_defined?(meth_name)
|
486
|
+
output.puts "Did you mean: show-method -M #{meth_name} ?"
|
487
|
+
end
|
488
|
+
output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
|
489
|
+
next
|
490
|
+
end
|
491
|
+
|
492
|
+
code = meth.source
|
493
|
+
file, line = meth.source_location
|
494
|
+
check_for_dynamically_defined_method.call(file)
|
495
|
+
|
496
|
+
output.puts "--\nFrom #{file} @ line #{line}:\n--"
|
497
|
+
|
498
|
+
if Pry.color
|
499
|
+
code = CodeRay.scan(code, :ruby).term
|
500
|
+
end
|
501
|
+
|
502
|
+
output.puts code
|
503
|
+
code
|
504
|
+
end
|
505
|
+
|
506
|
+
command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
|
507
|
+
if !command_name
|
508
|
+
output.puts "You must provide a command name."
|
509
|
+
next
|
510
|
+
end
|
511
|
+
|
512
|
+
if commands[command_name]
|
513
|
+
meth = commands[command_name][:action]
|
514
|
+
|
515
|
+
code = meth.source
|
516
|
+
file, line = meth.source_location
|
517
|
+
check_for_dynamically_defined_method.call(file)
|
518
|
+
|
519
|
+
output.puts "--\nFrom #{file} @ line #{line}:\n--"
|
520
|
+
|
521
|
+
if Pry.color
|
522
|
+
code = CodeRay.scan(code, :ruby).term
|
523
|
+
end
|
524
|
+
|
525
|
+
output.puts code
|
526
|
+
code
|
527
|
+
else
|
528
|
+
output.puts "No such command: #{command_name}."
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
|
533
|
+
break_level = break_level.to_i
|
534
|
+
nesting = opts[:nesting]
|
535
|
+
|
536
|
+
case break_level
|
537
|
+
when nesting.level
|
538
|
+
output.puts "Already at nesting level #{nesting.level}"
|
539
|
+
when (0...nesting.level)
|
540
|
+
throw(:breakout, break_level + 1)
|
541
|
+
else
|
542
|
+
max_nest_level = nesting.level - 1
|
543
|
+
output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
|
548
|
+
str = remove_first_word.call(opts[:val])
|
549
|
+
throw(:breakout, [opts[:nesting].level, target.eval(str)])
|
550
|
+
end
|
551
|
+
|
552
|
+
alias_command "quit", "exit", ""
|
553
|
+
alias_command "back", "exit", ""
|
554
|
+
|
555
|
+
command "game", "" do |highest|
|
556
|
+
highest = highest ? highest.to_i : 100
|
557
|
+
num = rand(highest)
|
558
|
+
output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
|
559
|
+
count = 0
|
560
|
+
while(true)
|
561
|
+
count += 1
|
562
|
+
str = Readline.readline("game > ", true)
|
563
|
+
break if str == "." || !str
|
564
|
+
val = str.to_i
|
565
|
+
output.puts "Too large!" if val > num
|
566
|
+
output.puts "Too small!" if val < num
|
567
|
+
if val == num
|
568
|
+
output.puts "Well done! You guessed right! It took you #{count} guesses."
|
569
|
+
break
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
command "east-coker", "" do
|
575
|
+
text = %{
|
576
|
+
--
|
577
|
+
Now the light falls
|
578
|
+
Across the open field, leaving the deep lane
|
579
|
+
Shuttered with branches, dark in the afternoon,
|
580
|
+
Where you lean against a bank while a van passes,
|
581
|
+
And the deep lane insists on the direction
|
582
|
+
Into the village, in the electric heat
|
583
|
+
Hypnotised. In a warm haze the sultry light
|
584
|
+
Is absorbed, not refracted, by grey stone.
|
585
|
+
The dahlias sleep in the empty silence.
|
586
|
+
Wait for the early owl.
|
587
|
+
-- T.S Eliot
|
588
|
+
}
|
589
|
+
output.puts text
|
590
|
+
text
|
591
|
+
end
|
592
|
+
|
593
|
+
command "cohen-poem", "" do
|
594
|
+
text = %{
|
595
|
+
--
|
596
|
+
When this American woman,
|
597
|
+
whose thighs are bound in casual red cloth,
|
598
|
+
comes thundering past my sitting place
|
599
|
+
like a forest-burning Mongol tribe,
|
600
|
+
the city is ravished
|
601
|
+
and brittle buildings of a hundred years
|
602
|
+
splash into the street;
|
603
|
+
and my eyes are burnt
|
604
|
+
for the embroidered Chinese girls,
|
605
|
+
already old,
|
606
|
+
and so small between the thin pines
|
607
|
+
on these enormous landscapes,
|
608
|
+
that if you turn your head
|
609
|
+
they are lost for hours.
|
610
|
+
-- Leonard Cohen
|
611
|
+
}
|
612
|
+
output.puts text
|
613
|
+
text
|
614
|
+
end
|
615
|
+
end
|
616
|
+
end
|