pry 0.6.7-i386-mswin32

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.
@@ -0,0 +1,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 "!", "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