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.
@@ -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 "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
32
- output.puts "Input buffer cleared!"
33
- opts[:eval_string].clear
34
- end
35
-
36
- command "!pry", "Start a Pry session on current self; this even works mid-expression." do
37
- Pry.start(target)
38
- end
39
-
40
- command "exit-program", "End the current program. Aliases: quit-program" do
41
- exit
42
- end
43
-
44
- alias_command "quit-program", "exit-program", ""
45
-
46
- command "toggle-color", "Toggle syntax highlighting." do
47
- Pry.color = !Pry.color
48
- output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
49
- end
50
-
51
- command "simple-prompt", "Toggle the simple prompt." do
52
- case Pry.active_instance.prompt
53
- when Pry::SIMPLE_PROMPT
54
- Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
55
- else
56
- Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
57
- end
58
- end
59
-
60
- command "nesting", "Show nesting information." do
61
- nesting = opts[:nesting]
62
-
63
- output.puts "Nesting status:"
64
- output.puts "--"
65
- nesting.each do |level, obj|
66
- if level == 0
67
- output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
68
- else
69
- output.puts "#{level}. #{Pry.view_clip(obj)}"
70
- end
71
- end
72
- end
73
-
74
- command "status", "Show status information." do
75
- nesting = opts[:nesting]
76
-
77
- output.puts "Status:"
78
- output.puts "--"
79
- output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
80
- output.puts "Nesting level: #{nesting.level}"
81
- output.puts "Pry version: #{Pry::VERSION}"
82
- output.puts "Ruby version: #{RUBY_VERSION}"
83
-
84
- mn = meth_name_from_binding.call(target)
85
- output.puts "Current method: #{mn ? mn : "N/A"}"
86
- output.puts "Pry instance: #{Pry.active_instance}"
87
- output.puts "Last result: #{Pry.view(Pry.last_result)}"
88
- end
89
-
90
- command "version", "Show Pry version." do
91
- output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
92
- end
93
-
94
- command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
95
- str = remove_first_word.call(opts[:val])
96
- throw(:breakout, [0, target.eval(str)])
97
- end
98
-
99
- alias_command "!@", "exit-all", ""
100
-
101
- command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
102
- options = {}
103
-
104
- # Set target local to the default -- note that we can set a different target for
105
- # ls if we like: e.g ls my_var
106
- target = target()
107
-
108
- OptionParser.new do |opts|
109
- opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
110
- List information about VAR (the current context by default).
111
- Shows local and instance variables by default.
112
- --
113
- }
114
- opts.on("-g", "--globals", "Display global variables.") do
115
- options[:g] = true
116
- end
117
-
118
- opts.on("-c", "--constants", "Display constants.") do
119
- options[:c] = true
120
- end
121
-
122
- opts.on("-l", "--locals", "Display locals.") do
123
- options[:l] = true
124
- end
125
-
126
- opts.on("-i", "--ivars", "Display instance variables.") do
127
- options[:i] = true
128
- end
129
-
130
- opts.on("-k", "--class-vars", "Display class variables.") do
131
- options[:k] = true
132
- end
133
-
134
- opts.on("-m", "--methods", "Display methods (public methods by default).") do
135
- options[:m] = true
136
- end
137
-
138
- opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
139
- options[:M] = true
140
- end
141
-
142
- opts.on("-P", "--public", "Display public methods (with -m).") do
143
- options[:P] = true
144
- end
145
-
146
- opts.on("-r", "--protected", "Display protected methods (with -m).") do
147
- options[:r] = true
148
- end
149
-
150
- opts.on("-p", "--private", "Display private methods (with -m).") do
151
- options[:p] = true
152
- end
153
-
154
- opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
155
- options[:s] = true
156
- end
157
-
158
- opts.on("-a", "--all", "Display all types of entries.") do
159
- options[:a] = true
160
- end
161
-
162
- opts.on("-v", "--verbose", "Verbose ouput.") do
163
- options[:v] = true
164
- end
165
-
166
- opts.on_tail("-h", "--help", "Show this message.") do
167
- output.puts opts
168
- options[:h] = true
169
- end
170
- end.order(args) do |new_target|
171
- target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
172
- end
173
-
174
- # exit if we've displayed help
175
- next if options[:h]
176
-
177
- # default is locals/ivars/class vars.
178
- # Only occurs when no options or when only option is verbose
179
- options.merge!({
180
- :l => true,
181
- :i => true,
182
- :k => true
183
- }) if options.empty? || (options.size == 1 && options[:v])
184
-
185
- # Display public methods by default if -m or -M switch is used.
186
- options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r])
187
-
188
- info = {}
189
- target_self = target.eval('self')
190
-
191
- # ensure we have a real boolean and not a `nil` (important when
192
- # interpolating in the string)
193
- options[:s] = !!options[:s]
194
-
195
- # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
196
- i = -1
197
-
198
- # Start collecting the entries selected by the user
199
- info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
200
- info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
201
-
202
- info["class variables"] = [if target_self.is_a?(Module)
203
- Array(target.eval("class_variables")).sort
204
- else
205
- Array(target.eval("self.class.class_variables")).sort
206
- end, i += 1] if options[:k] || options[:a]
207
-
208
- info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
209
-
210
- info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
211
-
212
- info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
213
-
214
- info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
215
-
216
- 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])
217
-
218
- 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])
219
-
220
- 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])
221
-
222
- # dealing with 1.8/1.9 compatibility issues :/
223
- csuper = options[:s]
224
- if Module.method(:constants).arity == 0
225
- csuper = nil
226
- end
227
-
228
- info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
229
- target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
230
-
231
- # verbose output?
232
- if options[:v]
233
-
234
- # verbose
235
- info.sort_by { |k, v| v.last }.each do |k, v|
236
- if !v.first.empty?
237
- output.puts "#{k}:\n--"
238
- if Pry.color
239
- output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
240
- else
241
- output.puts Pry.view(v.first)
242
- end
243
- output.puts
244
- end
245
- end
246
-
247
- # plain
248
- else
249
- list = info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+)
250
- if Pry.color
251
- output.puts CodeRay.scan(Pry.view(list), :ruby).term
252
- else
253
- output.puts Pry.view(list)
254
- end
255
- list
256
- end
257
- end
258
-
259
- command "cat-file", "Show output of file FILE" do |file_name|
260
- if !file_name
261
- output.puts "Must provide a file name."
262
- next
263
- end
264
-
265
- contents = File.read(file_name)
266
- output.puts contents
267
- contents
268
- end
269
-
270
- command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
271
- options = {}
272
- target = target()
273
- file_name = nil
274
-
275
- OptionParser.new do |opts|
276
- opts.banner = %{Usage: eval-file [OPTIONS] FILE
277
- Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
278
- e.g: eval-file -c self "hello.rb"
279
- --
280
- }
281
- opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
282
- options[:c] = true
283
- target = Pry.binding_for(target.eval(context))
284
- end
285
-
286
- opts.on_tail("-h", "--help", "This message.") do
287
- output.puts opts
288
- options[:h] = true
289
- end
290
- end.order(args) do |v|
291
- file_name = v
292
- end
293
-
294
- next if options[:h]
295
-
296
- if !file_name
297
- output.puts "You need to specify a file name. Type `eval-file --help` for help"
298
- next
299
- end
300
-
301
- old_constants = Object.constants
302
- if options[:c]
303
- target_self = target.eval('self')
304
- target.eval(File.read(file_name))
305
- output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
306
- else
307
- TOPLEVEL_BINDING.eval(File.read(file_name))
308
- output.puts "--\nEval'd '#{file_name}' at top-level."
309
- end
310
- new_constants = Object.constants - old_constants
311
- output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
312
- end
313
-
314
- command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
315
- if !obj
316
- output.puts "Must provide an object to inspect."
317
- next
318
- end
319
-
320
- output.puts Pry.view(target.eval("#{obj}"))
321
- end
322
-
323
- alias_command "inspect", "cat", ""
324
-
325
- 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|
326
- if !obj
327
- output.puts "Must provide an object."
328
- next
329
- end
330
-
331
- throw(:breakout, opts[:nesting].level) if obj == ".."
332
-
333
- if obj == "/"
334
- throw(:breakout, 1) if opts[:nesting].level > 0
335
- next
336
- end
337
-
338
- target.eval("#{obj}.pry")
339
- end
340
-
341
- command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
342
- options = {}
343
- target = target()
344
- meth_name = nil
345
-
346
- OptionParser.new do |opts|
347
- opts.banner = %{Usage: show-doc [OPTIONS] [METH]
348
- Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
349
- e.g show-doc hello_method
350
- --
351
- }
352
- opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
353
- options[:M] = true
354
- end
355
-
356
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
357
- target = Pry.binding_for(target.eval(context))
358
- end
359
-
360
- opts.on_tail("-h", "--help", "This message.") do
361
- output.puts opts
362
- options[:h] = true
363
- end
364
- end.order(args) do |v|
365
- meth_name = v
366
- end
367
-
368
- next if options[:h]
369
-
370
- if !meth_name
371
- output.puts "You need to specify a method. Type `show-doc --help` for help"
372
- next
373
- end
374
-
375
- begin
376
- if options[:M]
377
- meth = target.eval("instance_method(:#{meth_name})")
378
- else
379
- meth = target.eval("method(:#{meth_name})")
380
- end
381
- rescue
382
- output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
383
- next
384
- end
385
-
386
- doc = meth.comment
387
- file, line = meth.source_location
388
- check_for_dynamically_defined_method.call(file)
389
-
390
- output.puts "--\nFrom #{file} @ line ~#{line}:\n--"
391
-
392
- if Pry.color
393
- doc = CodeRay.scan(doc, :ruby).term
394
- end
395
-
396
- output.puts doc
397
- doc
398
- end
399
-
400
- command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
401
- options = {}
402
- target = target()
403
- meth_name = nil
404
-
405
- OptionParser.new do |opts|
406
- opts.banner = %{Usage: show-method [OPTIONS] [METH]
407
- Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
408
- e.g: show-method hello_method
409
- --
410
- }
411
- opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
412
- options[:M] = true
413
- end
414
-
415
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
416
- target = Pry.binding_for(target.eval(context))
417
- end
418
-
419
- opts.on_tail("-h", "--help", "This message.") do
420
- output.puts opts
421
- options[:h] = true
422
- end
423
- end.order(args) do |v|
424
- meth_name = v
425
- end
426
-
427
- next if options[:h]
428
-
429
- # If no method name is given then use current method, if it exists
430
- meth_name = meth_name_from_binding.call(target) if !meth_name
431
-
432
- if !meth_name
433
- output.puts "You need to specify a method. Type `show-method --help` for help"
434
- next
435
- end
436
-
437
- begin
438
- if options[:M]
439
- meth = target.eval("instance_method(:#{meth_name})")
440
- else
441
- meth = target.eval("method(:#{meth_name})")
442
- end
443
- rescue
444
- target_self = target.eval('self')
445
- if !options[:M]&& target_self.is_a?(Module) &&
446
- target_self.method_defined?(meth_name)
447
- output.puts "Did you mean: show-method -M #{meth_name} ?"
448
- end
449
- output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
450
- next
451
- end
452
-
453
- code = meth.source
454
- file, line = meth.source_location
455
- check_for_dynamically_defined_method.call(file)
456
-
457
- output.puts "--\nFrom #{file} @ line #{line}:\n--"
458
-
459
- if Pry.color
460
- code = CodeRay.scan(code, :ruby).term
461
- end
462
-
463
- output.puts code
464
- code
465
- end
466
-
467
- command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
468
- if !command_name
469
- output.puts "You must provide a command name."
470
- next
471
- end
472
-
473
- if commands[command_name]
474
- meth = commands[command_name][:action]
475
-
476
- code = meth.source
477
- file, line = meth.source_location
478
- check_for_dynamically_defined_method.call(file)
479
-
480
- output.puts "--\nFrom #{file} @ line #{line}:\n--"
481
-
482
- if Pry.color
483
- code = CodeRay.scan(code, :ruby).term
484
- end
485
-
486
- output.puts code
487
- code
488
- else
489
- output.puts "No such command: #{command_name}."
490
- end
491
- end
492
-
493
- command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
494
- break_level = break_level.to_i
495
- nesting = opts[:nesting]
496
-
497
- case break_level
498
- when nesting.level
499
- output.puts "Already at nesting level #{nesting.level}"
500
- when (0...nesting.level)
501
- throw(:breakout, break_level + 1)
502
- else
503
- max_nest_level = nesting.level - 1
504
- output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
505
- end
506
- end
507
-
508
- command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
509
- str = remove_first_word.call(opts[:val])
510
- throw(:breakout, [opts[:nesting].level, target.eval(str)])
511
- end
512
-
513
- alias_command "quit", "exit", ""
514
- alias_command "back", "exit", ""
515
-
516
- command "game", "" do |highest|
517
- highest = highest ? highest.to_i : 100
518
- num = rand(highest)
519
- output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
520
- count = 0
521
- while(true)
522
- count += 1
523
- str = Readline.readline("game > ", true)
524
- break if str == "." || !str
525
- val = str.to_i
526
- output.puts "Too large!" if val > num
527
- output.puts "Too small!" if val < num
528
- if val == num
529
- output.puts "Well done! You guessed right! It took you #{count} guesses."
530
- break
531
- end
532
- end
533
- end
534
-
535
- command "east-coker", "" do
536
- text = %{
537
- --
538
- Now the light falls
539
- Across the open field, leaving the deep lane
540
- Shuttered with branches, dark in the afternoon,
541
- Where you lean against a bank while a van passes,
542
- And the deep lane insists on the direction
543
- Into the village, in the electric heat
544
- Hypnotised. In a warm haze the sultry light
545
- Is absorbed, not refracted, by grey stone.
546
- The dahlias sleep in the empty silence.
547
- Wait for the early owl.
548
- -- T.S Eliot
549
- }
550
- output.puts text
551
- text
552
- end
553
-
554
- command "cohen-poem", "" do
555
- text = %{
556
- --
557
- When this American woman,
558
- whose thighs are bound in casual red cloth,
559
- comes thundering past my sitting place
560
- like a forest-burning Mongol tribe,
561
- the city is ravished
562
- and brittle buildings of a hundred years
563
- splash into the street;
564
- and my eyes are burnt
565
- for the embroidered Chinese girls,
566
- already old,
567
- and so small between the thin pines
568
- on these enormous landscapes,
569
- that if you turn your head
570
- they are lost for hours.
571
- -- Leonard Cohen
572
- }
573
- output.puts text
574
- text
575
- end
576
- end
577
- end
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