pry 0.6.8-java

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,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 "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