pry 0.7.7.1-i386-mingw32 → 0.7.7.2-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,718 @@
1
+ require "optparse"
2
+ require "method_source"
3
+ require "pry/command_base"
4
+ require "pry/pry_instance"
5
+
6
+ begin
7
+
8
+ # YARD crashes on rbx, so do not require it
9
+ if !Object.const_defined?(:RUBY_ENGINE) || RUBY_ENGINE !~ /rbx/
10
+ require "pry-doc"
11
+ end
12
+ rescue LoadError
13
+ end
14
+
15
+ class Pry
16
+
17
+ # Default commands used by Pry.
18
+ class Commands < CommandBase
19
+
20
+ # We make this a lambda to avoid documenting it
21
+ meth_name_from_binding = lambda do |b|
22
+ meth_name = b.eval('__method__')
23
+
24
+ # :__script__ for rubinius
25
+ if [:__script__, nil, :__binding__, :__binding_impl__].include?(meth_name)
26
+ nil
27
+ else
28
+ meth_name
29
+ end
30
+ end
31
+
32
+ check_for_dynamically_defined_method = lambda do |meth|
33
+ file, _ = meth.source_location
34
+ if file =~ /(\(.*\))|<.*>/
35
+ raise "Cannot retrieve source for dynamically defined method."
36
+ end
37
+ end
38
+
39
+ remnnove_first_word = lambda do |text|
40
+ text.split.drop(1).join(' ')
41
+ end
42
+
43
+ get_method_object = lambda do |meth_name, target, options|
44
+ if !meth_name
45
+ return nil
46
+ end
47
+
48
+ if options[:M]
49
+ target.eval("instance_method(:#{meth_name})")
50
+ elsif options[:m]
51
+ target.eval("method(:#{meth_name})")
52
+ else
53
+ begin
54
+ target.eval("instance_method(:#{meth_name})")
55
+ rescue
56
+ begin
57
+ target.eval("method(:#{meth_name})")
58
+ rescue
59
+ return nil
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ make_header = lambda do |meth, code_type|
66
+ file, line = meth.source_location
67
+ header = case code_type
68
+ when :ruby
69
+ "--\nFrom #{file} @ line #{line}:\n--"
70
+ else
71
+ "--\nFrom Ruby Core (C Method):\n--"
72
+ end
73
+ end
74
+
75
+ is_a_c_method = lambda do |meth|
76
+ meth.source_location.nil?
77
+ end
78
+
79
+ should_use_pry_doc = lambda do |meth|
80
+ Pry.has_pry_doc && is_a_c_method.call(meth)
81
+ end
82
+
83
+ code_type_for = lambda do |meth|
84
+ # only C methods
85
+ if should_use_pry_doc.call(meth)
86
+ info = Pry::MethodInfo.info_for(meth)
87
+ if info && info.source
88
+ code_type = :c
89
+ else
90
+ output.puts "Cannot find C method: #{meth.name}"
91
+ code_type = nil
92
+ end
93
+ else
94
+ if is_a_c_method.call(meth)
95
+ output.puts "Cannot locate this method: #{meth.name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
96
+ code_type = nil
97
+ else
98
+ check_for_dynamically_defined_method.call(meth)
99
+ code_type = :ruby
100
+ end
101
+ end
102
+ code_type
103
+ end
104
+
105
+ command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
106
+ output.puts "Input buffer cleared!"
107
+ opts[:eval_string].clear
108
+ end
109
+
110
+ command "!pry", "Start a Pry session on current self; this even works mid-expression." do
111
+ Pry.start(target)
112
+ end
113
+
114
+ command "exit-program", "End the current program. Aliases: quit-program, !!!" do
115
+ exit
116
+ end
117
+
118
+ alias_command "quit-program", "exit-program", ""
119
+ alias_command "!!!", "exit-program", ""
120
+
121
+ command "toggle-color", "Toggle syntax highlighting." do
122
+ Pry.color = !Pry.color
123
+ output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
124
+ end
125
+
126
+ command "simple-prompt", "Toggle the simple prompt." do
127
+ case Pry.active_instance.prompt
128
+ when Pry::SIMPLE_PROMPT
129
+ Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
130
+ else
131
+ Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
132
+ end
133
+ end
134
+
135
+ command "nesting", "Show nesting information." do
136
+ nesting = opts[:nesting]
137
+
138
+ output.puts "Nesting status:"
139
+ output.puts "--"
140
+ nesting.each do |level, obj|
141
+ if level == 0
142
+ output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
143
+ else
144
+ output.puts "#{level}. #{Pry.view_clip(obj)}"
145
+ end
146
+ end
147
+ end
148
+
149
+ command "status", "Show status information." do
150
+ nesting = opts[:nesting]
151
+
152
+ output.puts "Status:"
153
+ output.puts "--"
154
+ output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
155
+ output.puts "Nesting level: #{nesting.level}"
156
+ output.puts "Pry version: #{Pry::VERSION}"
157
+ output.puts "Ruby version: #{RUBY_VERSION}"
158
+
159
+ mn = meth_name_from_binding.call(target)
160
+ output.puts "Current method: #{mn ? mn : "N/A"}"
161
+ output.puts "Pry instance: #{Pry.active_instance}"
162
+ output.puts "Last result: #{Pry.view(Pry.last_result)}"
163
+ end
164
+
165
+ command "whereami", "Show the code context for the session. Shows AROUND lines around the invocation line. AROUND defaults to 5 lines. " do |num|
166
+ file = target.eval('__FILE__')
167
+ line_num = target.eval('__LINE__')
168
+ klass = target.eval('self.class')
169
+
170
+ if num
171
+ i_num = num.to_i
172
+ else
173
+ i_num = 5
174
+ end
175
+
176
+ meth_name = meth_name_from_binding.call(target)
177
+ meth_name = "N/A" if !meth_name
178
+
179
+ if file =~ /(\(.*\))|<.*>/ || file == ""
180
+ output.puts "Cannot find local context. Did you use `binding.pry` ?"
181
+ next
182
+ end
183
+
184
+ output.puts "--\nFrom #{file} @ line #{line_num} in #{klass}##{meth_name}:\n--"
185
+
186
+ # This method inspired by http://rubygems.org/gems/ir_b
187
+ File.open(file).each_with_index do |line, index|
188
+ line_n = index + 1
189
+ next unless line_n > (line_num - i_num - 1)
190
+ break if line_n > (line_num + i_num)
191
+ if line_n == line_num
192
+ code =" =>#{line_n.to_s.rjust(3)}: #{line.chomp}"
193
+ if Pry.color
194
+ code = CodeRay.scan(code, :ruby).term
195
+ end
196
+ output.puts code
197
+ code
198
+ else
199
+ code = "#{line_n.to_s.rjust(6)}: #{line.chomp}"
200
+ if Pry.color
201
+ code = CodeRay.scan(code, :ruby).term
202
+ end
203
+ output.puts code
204
+ code
205
+ end
206
+ end
207
+ end
208
+
209
+ command "version", "Show Pry version." do
210
+ output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
211
+ end
212
+
213
+ command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
214
+ str = remove_first_word.call(opts[:val])
215
+ throw(:breakout, [0, target.eval(str)])
216
+ end
217
+
218
+ alias_command "!@", "exit-all", ""
219
+
220
+ command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
221
+ options = {}
222
+
223
+ # Set target local to the default -- note that we can set a different target for
224
+ # ls if we like: e.g ls my_var
225
+ target = target()
226
+
227
+ OptionParser.new do |opts|
228
+ opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
229
+ List information about VAR (the current context by default).
230
+ Shows local and instance variables by default.
231
+ --
232
+ }
233
+ opts.on("-g", "--globals", "Display global variables.") do
234
+ options[:g] = true
235
+ end
236
+
237
+ opts.on("-c", "--constants", "Display constants.") do
238
+ options[:c] = true
239
+ end
240
+
241
+ opts.on("-l", "--locals", "Display locals.") do
242
+ options[:l] = true
243
+ end
244
+
245
+ opts.on("-i", "--ivars", "Display instance variables.") do
246
+ options[:i] = true
247
+ end
248
+
249
+ opts.on("-k", "--class-vars", "Display class variables.") do
250
+ options[:k] = true
251
+ end
252
+
253
+ opts.on("-m", "--methods", "Display methods (public methods by default).") do
254
+ options[:m] = true
255
+ end
256
+
257
+ opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
258
+ options[:M] = true
259
+ end
260
+
261
+ opts.on("-P", "--public", "Display public methods (with -m).") do
262
+ options[:P] = true
263
+ end
264
+
265
+ opts.on("-r", "--protected", "Display protected methods (with -m).") do
266
+ options[:r] = true
267
+ end
268
+
269
+ opts.on("-p", "--private", "Display private methods (with -m).") do
270
+ options[:p] = true
271
+ end
272
+
273
+ opts.on("-j", "--just-singletons", "Display just the singleton methods (with -m).") do
274
+ options[:j] = true
275
+ end
276
+
277
+ opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
278
+ options[:s] = true
279
+ end
280
+
281
+ opts.on("-a", "--all", "Display all types of entries.") do
282
+ options[:a] = true
283
+ end
284
+
285
+ opts.on("-v", "--verbose", "Verbose ouput.") do
286
+ options[:v] = true
287
+ end
288
+
289
+ opts.on_tail("-h", "--help", "Show this message.") do
290
+ output.puts opts
291
+ options[:h] = true
292
+ end
293
+ end.order(args) do |new_target|
294
+ target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
295
+ end
296
+
297
+ # exit if we've displayed help
298
+ next if options[:h]
299
+
300
+ # default is locals/ivars/class vars.
301
+ # Only occurs when no options or when only option is verbose
302
+ options.merge!({
303
+ :l => true,
304
+ :i => true,
305
+ :k => true
306
+ }) if options.empty? || (options.size == 1 && options[:v])
307
+
308
+ # Display public methods by default if -m or -M switch is used.
309
+ options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r] || options[:j])
310
+
311
+ info = {}
312
+ target_self = target.eval('self')
313
+
314
+ # ensure we have a real boolean and not a `nil` (important when
315
+ # interpolating in the string)
316
+ options[:s] = !!options[:s]
317
+
318
+ # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
319
+ i = -1
320
+
321
+ # Start collecting the entries selected by the user
322
+ info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
323
+ info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
324
+
325
+ info["class variables"] = [if target_self.is_a?(Module)
326
+ Array(target.eval("class_variables")).sort
327
+ else
328
+ Array(target.eval("self.class.class_variables")).sort
329
+ end, i += 1] if options[:k] || options[:a]
330
+
331
+ info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
332
+
333
+ info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
334
+
335
+ info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
336
+
337
+ info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
338
+
339
+ info["just singleton methods"] = [Array(target.eval("methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:j]) || options[:a]
340
+
341
+ 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])
342
+
343
+ 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])
344
+
345
+ 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])
346
+
347
+ # dealing with 1.8/1.9 compatibility issues :/
348
+ csuper = options[:s]
349
+ if Module.method(:constants).arity == 0
350
+ csuper = nil
351
+ end
352
+
353
+ info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
354
+ target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
355
+
356
+ # verbose output?
357
+ if options[:v]
358
+
359
+ # verbose
360
+ info.sort_by { |k, v| v.last }.each do |k, v|
361
+ if !v.first.empty?
362
+ output.puts "#{k}:\n--"
363
+ if Pry.color
364
+ output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
365
+ else
366
+ output.puts Pry.view(v.first)
367
+ end
368
+ output.puts
369
+ end
370
+ end
371
+
372
+ # plain
373
+ else
374
+ list = info.values.sort_by(&:last).map(&:first).inject(&:+)
375
+ list.uniq! if list
376
+ if Pry.color
377
+ output.puts CodeRay.scan(Pry.view(list), :ruby).term
378
+ else
379
+ output.puts Pry.view(list)
380
+ end
381
+ list
382
+ end
383
+ end
384
+
385
+ command "cat-file", "Show output of file FILE" do |file_name|
386
+ if !file_name
387
+ output.puts "Must provide a file name."
388
+ next
389
+ end
390
+
391
+ contents = File.read(File.expand_path(file_name))
392
+ output.puts contents
393
+ contents
394
+ end
395
+
396
+ command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
397
+ options = {}
398
+ target = target()
399
+ file_name = nil
400
+
401
+ OptionParser.new do |opts|
402
+ opts.banner = %{Usage: eval-file [OPTIONS] FILE
403
+ Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
404
+ e.g: eval-file -c self "hello.rb"
405
+ --
406
+ }
407
+ opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
408
+ options[:c] = true
409
+ target = Pry.binding_for(target.eval(context))
410
+ end
411
+
412
+ opts.on_tail("-h", "--help", "This message.") do
413
+ output.puts opts
414
+ options[:h] = true
415
+ end
416
+ end.order(args) do |v|
417
+ file_name = v
418
+ end
419
+
420
+ next if options[:h]
421
+
422
+ if !file_name
423
+ output.puts "You need to specify a file name. Type `eval-file --help` for help"
424
+ next
425
+ end
426
+
427
+ old_constants = Object.constants
428
+ if options[:c]
429
+ target_self = target.eval('self')
430
+ target.eval(File.read(File.expand_path(file_name)))
431
+ output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
432
+ else
433
+ TOPLEVEL_BINDING.eval(File.read(File.expand_path(file_name)))
434
+ output.puts "--\nEval'd '#{file_name}' at top-level."
435
+ end
436
+ new_constants = Object.constants - old_constants
437
+ output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
438
+ end
439
+
440
+ command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
441
+ if !obj
442
+ output.puts "Must provide an object to inspect."
443
+ next
444
+ end
445
+
446
+ output.puts Pry.view(target.eval("#{obj}"))
447
+ end
448
+
449
+ alias_command "inspect", "cat", ""
450
+
451
+ 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|
452
+ if !obj
453
+ output.puts "Must provide an object."
454
+ next
455
+ end
456
+
457
+ throw(:breakout, opts[:nesting].level) if obj == ".."
458
+
459
+ if obj == "/"
460
+ throw(:breakout, 1) if opts[:nesting].level > 0
461
+ next
462
+ end
463
+
464
+ target.eval("#{obj}").pry
465
+ end
466
+
467
+ process_comment_markup = lambda do |comment, code_type|
468
+ comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
469
+ gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
470
+ gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[34m#{$1}\e[0m" : $1 }.
471
+ gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
472
+ gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
473
+ gsub(/`(?:\s*\n)?(.*?)\s*`/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
474
+ gsub(/^@(param|return|example|option|yield|attr|attr_reader|attr_writer)/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 }
475
+ end
476
+
477
+ # strip leading whitespace but preserve indentation
478
+ strip_leading_whitespace = lambda do |text|
479
+ leading_spaces = text.lines.first[/^(\s+)/, 1]
480
+ text.gsub(/^#{leading_spaces}/, '')
481
+ end
482
+
483
+ strip_leading_hash_and_whitespace_from_ruby_comments = lambda do |comment|
484
+ comment = comment.dup
485
+ comment.gsub!(/^\s*#/, '')
486
+ strip_leading_whitespace.call(comment)
487
+ end
488
+
489
+ command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
490
+ options = {}
491
+ target = target()
492
+ meth_name = nil
493
+
494
+ OptionParser.new do |opts|
495
+ opts.banner = %{Usage: show-doc [OPTIONS] [METH]
496
+ Show the comments above method METH. Tries instance methods first and then methods by default.
497
+ e.g show-doc hello_method
498
+ --
499
+ }
500
+ opts.on("-M", "--instance-methods", "Operate on instance methods.") do
501
+ options[:M] = true
502
+ end
503
+
504
+ opts.on("-m", "--methods", "Operate on methods.") do
505
+ options[:m] = true
506
+ end
507
+
508
+ opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
509
+ target = Pry.binding_for(target.eval(context))
510
+ end
511
+
512
+ opts.on_tail("-h", "--help", "This message.") do
513
+ output.puts opts
514
+ options[:h] = true
515
+ end
516
+ end.order(args) do |v|
517
+ meth_name = v
518
+ end
519
+
520
+ next if options[:h]
521
+
522
+ if (meth = get_method_object.call(meth_name, target, options)).nil?
523
+ output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
524
+ next
525
+ end
526
+
527
+ case code_type = code_type_for.call(meth)
528
+ when nil
529
+ next
530
+ when :c
531
+ doc = Pry::MethodInfo.info_for(meth).docstring
532
+ when :ruby
533
+ doc = meth.comment
534
+ doc = strip_leading_hash_and_whitespace_from_ruby_comments.call(doc)
535
+ end
536
+
537
+ doc = process_comment_markup.call(doc, code_type)
538
+ output.puts make_header.call(meth, code_type)
539
+ output.puts doc
540
+ doc
541
+ end
542
+
543
+ strip_comments_from_c_code = lambda do |code|
544
+ code.sub /\A\s*\/\*.*?\*\/\s*/m, ''
545
+ end
546
+
547
+ command "show-method", "Show the source for METH. Type `show-method --help` for more info. Aliases: show-source" do |*args|
548
+ options = {}
549
+ target = target()
550
+ meth_name = nil
551
+
552
+ OptionParser.new do |opts|
553
+ opts.banner = %{Usage: show-method [OPTIONS] [METH]
554
+ Show the source for method METH. Tries instance methods first and then methods by default.
555
+ e.g: show-method hello_method
556
+ --
557
+ }
558
+ opts.on("-M", "--instance-methods", "Operate on instance methods.") do
559
+ options[:M] = true
560
+ end
561
+
562
+ opts.on("-m", "--methods", "Operate on methods.") do
563
+ options[:m] = true
564
+ end
565
+
566
+ opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
567
+ target = Pry.binding_for(target.eval(context))
568
+ end
569
+
570
+ opts.on_tail("-h", "--help", "This message.") do
571
+ output.puts opts
572
+ options[:h] = true
573
+ end
574
+ end.order(args) do |v|
575
+ meth_name = v
576
+ end
577
+
578
+ next if options[:h]
579
+
580
+ meth_name = meth_name_from_binding.call(target) if !meth_name
581
+
582
+ if (meth = get_method_object.call(meth_name, target, options)).nil?
583
+ output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
584
+ next
585
+ end
586
+
587
+ case code_type = code_type_for.call(meth)
588
+ when nil
589
+ next
590
+ when :c
591
+ code = Pry::MethodInfo.info_for(meth).source
592
+ code = strip_comments_from_c_code.call(code)
593
+ when :ruby
594
+ code = strip_leading_whitespace.call(meth.source)
595
+ end
596
+
597
+ output.puts make_header.call(meth, code_type)
598
+ if Pry.color
599
+ code = CodeRay.scan(code, code_type).term
600
+ end
601
+
602
+ output.puts code
603
+ code
604
+ end
605
+
606
+ alias_command "show-source", "show-method", ""
607
+
608
+ command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
609
+ if !command_name
610
+ output.puts "You must provide a command name."
611
+ next
612
+ end
613
+
614
+ if commands[command_name]
615
+ meth = commands[command_name][:action]
616
+
617
+ code = strip_leading_whitespace.call(meth.source)
618
+ file, line = meth.source_location
619
+ check_for_dynamically_defined_method.call(meth)
620
+
621
+ output.puts "--\nFrom #{file} @ line #{line}:\n--"
622
+
623
+ if Pry.color
624
+ code = CodeRay.scan(code, :ruby).term
625
+ end
626
+
627
+ output.puts code
628
+ code
629
+ else
630
+ output.puts "No such command: #{command_name}."
631
+ end
632
+ end
633
+
634
+ command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
635
+ break_level = break_level.to_i
636
+ nesting = opts[:nesting]
637
+
638
+ case break_level
639
+ when nesting.level
640
+ output.puts "Already at nesting level #{nesting.level}"
641
+ when (0...nesting.level)
642
+ throw(:breakout, break_level + 1)
643
+ else
644
+ max_nest_level = nesting.level - 1
645
+ output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
646
+ end
647
+ end
648
+
649
+ command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
650
+ str = remove_first_word.call(opts[:val])
651
+ throw(:breakout, [opts[:nesting].level, target.eval(str)])
652
+ end
653
+
654
+ alias_command "quit", "exit", ""
655
+ alias_command "back", "exit", ""
656
+
657
+ command "game", "" do |highest|
658
+ highest = highest ? highest.to_i : 100
659
+ num = rand(highest)
660
+ output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
661
+ count = 0
662
+ while(true)
663
+ count += 1
664
+ str = Readline.readline("game > ", true)
665
+ break if str == "." || !str
666
+ val = str.to_i
667
+ output.puts "Too large!" if val > num
668
+ output.puts "Too small!" if val < num
669
+ if val == num
670
+ output.puts "Well done! You guessed right! It took you #{count} guesses."
671
+ break
672
+ end
673
+ end
674
+ end
675
+
676
+ command "east-coker", "" do
677
+ text = %{
678
+ --
679
+ Now the light falls
680
+ Across the open field, leaving the deep lane
681
+ Shuttered with branches, dark in the afternoon,
682
+ Where you lean against a bank while a van passes,
683
+ And the deep lane insists on the direction
684
+ Into the village, in the electric heat
685
+ Hypnotised. In a warm haze the sultry light
686
+ Is absorbed, not refracted, by grey stone.
687
+ The dahlias sleep in the empty silence.
688
+ Wait for the early owl.
689
+ -- T.S Eliot
690
+ }
691
+ output.puts text
692
+ text
693
+ end
694
+
695
+ command "cohen-poem", "" do
696
+ text = %{
697
+ --
698
+ When this American woman,
699
+ whose thighs are bound in casual red cloth,
700
+ comes thundering past my sitting place
701
+ like a forest-burning Mongol tribe,
702
+ the city is ravished
703
+ and brittle buildings of a hundred years
704
+ splash into the street;
705
+ and my eyes are burnt
706
+ for the embroidered Chinese girls,
707
+ already old,
708
+ and so small between the thin pines
709
+ on these enormous landscapes,
710
+ that if you turn your head
711
+ they are lost for hours.
712
+ -- Leonard Cohen
713
+ }
714
+ output.puts text
715
+ text
716
+ end
717
+ end
718
+ end