pry 0.7.7.1-i386-mswin32 → 0.7.7.2-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,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