pry 0.10.4-java → 0.11.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -18
- data/LICENSE +1 -1
- data/README.md +32 -31
- data/bin/pry +3 -7
- data/lib/pry.rb +4 -4
- data/lib/pry/basic_object.rb +6 -0
- data/lib/pry/cli.rb +39 -34
- data/lib/pry/code.rb +6 -1
- data/lib/pry/code/code_file.rb +8 -2
- data/lib/pry/code_object.rb +23 -0
- data/lib/pry/color_printer.rb +20 -11
- data/lib/pry/command.rb +40 -16
- data/lib/pry/command_set.rb +9 -2
- data/lib/pry/commands/cat/exception_formatter.rb +11 -10
- data/lib/pry/commands/cat/file_formatter.rb +7 -3
- data/lib/pry/commands/code_collector.rb +16 -14
- data/lib/pry/commands/easter_eggs.rb +9 -9
- data/lib/pry/commands/edit.rb +7 -3
- data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
- data/lib/pry/commands/find_method.rb +1 -1
- data/lib/pry/commands/gem_open.rb +1 -1
- data/lib/pry/commands/gem_readme.rb +25 -0
- data/lib/pry/commands/gem_search.rb +40 -0
- data/lib/pry/commands/hist.rb +2 -2
- data/lib/pry/commands/jump_to.rb +7 -7
- data/lib/pry/commands/ls.rb +3 -1
- data/lib/pry/commands/ls/constants.rb +12 -1
- data/lib/pry/commands/ls/formatter.rb +1 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
- data/lib/pry/commands/ls/self_methods.rb +2 -0
- data/lib/pry/commands/play.rb +2 -2
- data/lib/pry/commands/reload_code.rb +2 -2
- data/lib/pry/commands/ri.rb +4 -0
- data/lib/pry/commands/shell_command.rb +34 -8
- data/lib/pry/commands/show_info.rb +10 -2
- data/lib/pry/commands/watch_expression/expression.rb +1 -1
- data/lib/pry/commands/whereami.rb +7 -6
- data/lib/pry/config.rb +3 -16
- data/lib/pry/config/behavior.rb +140 -49
- data/lib/pry/config/default.rb +21 -33
- data/lib/pry/config/memoization.rb +44 -0
- data/lib/pry/core_extensions.rb +12 -2
- data/lib/pry/editor.rb +1 -1
- data/lib/pry/exceptions.rb +1 -1
- data/lib/pry/forwardable.rb +23 -0
- data/lib/pry/helpers/base_helpers.rb +6 -10
- data/lib/pry/helpers/documentation_helpers.rb +1 -0
- data/lib/pry/helpers/options_helpers.rb +1 -1
- data/lib/pry/helpers/text.rb +69 -75
- data/lib/pry/history.rb +22 -1
- data/lib/pry/history_array.rb +1 -1
- data/lib/pry/hooks.rb +48 -107
- data/lib/pry/indent.rb +6 -2
- data/lib/pry/input_completer.rb +138 -120
- data/lib/pry/last_exception.rb +2 -2
- data/lib/pry/method.rb +15 -15
- data/lib/pry/method/disowned.rb +1 -0
- data/lib/pry/method/patcher.rb +0 -3
- data/lib/pry/output.rb +37 -38
- data/lib/pry/pager.rb +11 -8
- data/lib/pry/plugins.rb +20 -5
- data/lib/pry/pry_class.rb +30 -4
- data/lib/pry/pry_instance.rb +8 -6
- data/lib/pry/repl.rb +38 -8
- data/lib/pry/repl_file_loader.rb +1 -1
- data/lib/pry/rubygem.rb +3 -1
- data/lib/pry/slop.rb +661 -0
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +196 -0
- data/lib/pry/slop/option.rb +208 -0
- data/lib/pry/terminal.rb +16 -5
- data/lib/pry/test/helper.rb +12 -3
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +7 -7
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +7 -13
- metadata +14 -19
data/lib/pry/code.rb
CHANGED
@@ -92,7 +92,7 @@ class Pry
|
|
92
92
|
LOC.new(line, lineno + start_line.to_i) }
|
93
93
|
@code_type = code_type
|
94
94
|
|
95
|
-
@with_marker = @with_indentation = nil
|
95
|
+
@with_marker = @with_indentation = @with_line_numbers = nil
|
96
96
|
end
|
97
97
|
|
98
98
|
# Append the given line. +lineno+ is one more than the last existing
|
@@ -337,6 +337,11 @@ class Pry
|
|
337
337
|
end
|
338
338
|
undef =~
|
339
339
|
|
340
|
+
# Check whether String responds to missing methods.
|
341
|
+
def respond_to_missing?(name, include_all=false)
|
342
|
+
''.respond_to?(name, include_all)
|
343
|
+
end
|
344
|
+
|
340
345
|
protected
|
341
346
|
|
342
347
|
# An abstraction of the `dup.instance_eval` pattern used throughout this
|
data/lib/pry/code/code_file.rb
CHANGED
@@ -17,8 +17,12 @@ class Pry
|
|
17
17
|
%w(.c .h) => :c,
|
18
18
|
%w(.rhtml) => :rhtml,
|
19
19
|
%w(.yaml .yml) => :yaml,
|
20
|
-
%w(.cpp .hpp .cc .h cxx) => :cpp,
|
21
|
-
%w(.rb .ru .irbrc .gemspec .pryrc) => :ruby,
|
20
|
+
%w(.cpp .hpp .cc .h .cxx) => :cpp,
|
21
|
+
%w(.rb .ru .irbrc .gemspec .pryrc .rake) => :ruby,
|
22
|
+
}
|
23
|
+
|
24
|
+
FILES = {
|
25
|
+
%w(Gemfile Rakefile Guardfile Capfile) => :ruby
|
22
26
|
}
|
23
27
|
|
24
28
|
# @return [Symbol] The type of code stored in this wrapper.
|
@@ -79,6 +83,8 @@ class Pry
|
|
79
83
|
def type_from_filename(filename, default = :unknown)
|
80
84
|
_, @code_type = EXTENSIONS.find do |k, _|
|
81
85
|
k.any? { |ext| ext == File.extname(filename) }
|
86
|
+
end || FILES.find do |k, _|
|
87
|
+
k.any? { |file_name| file_name == File.basename(filename) }
|
82
88
|
end
|
83
89
|
|
84
90
|
code_type || default
|
data/lib/pry/code_object.rb
CHANGED
@@ -37,6 +37,28 @@ class Pry
|
|
37
37
|
def command?
|
38
38
|
is_a?(Module) && self <= Pry::Command
|
39
39
|
end
|
40
|
+
|
41
|
+
# @return [Boolean] `true` if this module was defined by means of the C API,
|
42
|
+
# `false` if it's a Ruby module.
|
43
|
+
# @note If a module defined by C was extended with a lot of methods written
|
44
|
+
# in Ruby, this method would fail.
|
45
|
+
def c_module?
|
46
|
+
if is_a?(WrappedModule)
|
47
|
+
|
48
|
+
method_locations = wrapped.methods(false).map do |m|
|
49
|
+
wrapped.method(m).source_location
|
50
|
+
end
|
51
|
+
|
52
|
+
method_locations.concat(wrapped.instance_methods(false).map do |m|
|
53
|
+
wrapped.instance_method(m).source_location
|
54
|
+
end)
|
55
|
+
|
56
|
+
c_methods = method_locations.grep(nil).count
|
57
|
+
ruby_methods = method_locations.count - c_methods
|
58
|
+
|
59
|
+
c_methods > ruby_methods
|
60
|
+
end
|
61
|
+
end
|
40
62
|
end
|
41
63
|
|
42
64
|
include Pry::Helpers::CommandHelpers
|
@@ -147,6 +169,7 @@ class Pry
|
|
147
169
|
# @return [Boolean]
|
148
170
|
def safe_to_evaluate?(str)
|
149
171
|
return true if str.strip == "self"
|
172
|
+
return false if str =~ /%/
|
150
173
|
kind = target.eval("defined?(#{str})")
|
151
174
|
kind =~ /variable|constant/
|
152
175
|
end
|
data/lib/pry/color_printer.rb
CHANGED
@@ -12,8 +12,8 @@ class Pry
|
|
12
12
|
|
13
13
|
CodeRay::Encoders::Terminal::TOKEN_COLORS[:comment][:self] = "\e[1;34m"
|
14
14
|
|
15
|
-
def self.pp(obj, out = $>, width = 79)
|
16
|
-
q = ColorPrinter.new(out, width)
|
15
|
+
def self.pp(obj, out = $>, width = 79, newline = "\n")
|
16
|
+
q = ColorPrinter.new(out, width, newline)
|
17
17
|
q.guard_inspect_key { q.pp obj }
|
18
18
|
q.flush
|
19
19
|
out << "\n"
|
@@ -31,17 +31,26 @@ class Pry
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def pp(obj)
|
34
|
-
|
34
|
+
if String === obj
|
35
|
+
# Avoid calling Ruby 2.4+ String#pretty_print that prints multiline
|
36
|
+
# Strings prettier
|
37
|
+
Object.instance_method(:pretty_print).bind(obj).call
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
35
41
|
rescue => e
|
36
42
|
raise if e.is_a? Pry::Pager::StopPaging
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
begin
|
44
|
+
str = obj.inspect
|
45
|
+
rescue Exception
|
46
|
+
# Read the class name off of the singleton class to provide a default
|
47
|
+
# inspect.
|
48
|
+
singleton = class << obj; self; end
|
49
|
+
ancestors = Pry::Method.safe_send(singleton, :ancestors)
|
50
|
+
klass = ancestors.reject { |k| k == singleton }.first
|
51
|
+
obj_id = obj.__id__.to_s(16) rescue 0
|
52
|
+
str = "#<#{klass}:0x#{obj_id}>"
|
53
|
+
end
|
45
54
|
|
46
55
|
text highlight_object_literal(str)
|
47
56
|
end
|
data/lib/pry/command.rb
CHANGED
@@ -52,7 +52,7 @@ class Pry
|
|
52
52
|
# Define or get the command's banner
|
53
53
|
def banner(arg=nil)
|
54
54
|
@banner = arg if arg
|
55
|
-
@banner
|
55
|
+
@banner ||= description
|
56
56
|
end
|
57
57
|
|
58
58
|
def block
|
@@ -167,11 +167,12 @@ class Pry
|
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
|
+
# @deprecated Replaced with {Pry::Hooks#add_hook}. Left for compatibility.
|
170
171
|
# Store hooks to be run before or after the command body.
|
171
172
|
# @see {Pry::CommandSet#before_command}
|
172
173
|
# @see {Pry::CommandSet#after_command}
|
173
174
|
def hooks
|
174
|
-
|
175
|
+
Pry.hooks
|
175
176
|
end
|
176
177
|
|
177
178
|
def command_regex
|
@@ -223,6 +224,7 @@ class Pry
|
|
223
224
|
attr_accessor :arg_string
|
224
225
|
attr_accessor :context
|
225
226
|
attr_accessor :command_set
|
227
|
+
attr_accessor :hooks
|
226
228
|
attr_accessor :_pry_
|
227
229
|
|
228
230
|
# The block we pass *into* a command so long as `:takes_block` is
|
@@ -271,6 +273,7 @@ class Pry
|
|
271
273
|
self.output = context[:output]
|
272
274
|
self.eval_string = context[:eval_string]
|
273
275
|
self.command_set = context[:command_set]
|
276
|
+
self.hooks = context[:hooks]
|
274
277
|
self._pry_ = context[:pry_instance]
|
275
278
|
end
|
276
279
|
|
@@ -424,10 +427,20 @@ class Pry
|
|
424
427
|
raise CommandError, "The command '#{command_name}' requires an argument."
|
425
428
|
end
|
426
429
|
|
427
|
-
ret =
|
430
|
+
ret = use_unpatched_symbol do
|
431
|
+
call_with_hooks(*args)
|
432
|
+
end
|
428
433
|
command_options[:keep_retval] ? ret : void
|
429
434
|
end
|
430
435
|
|
436
|
+
def use_unpatched_symbol
|
437
|
+
call_method = Symbol.method_defined?(:call) && Symbol.instance_method(:call)
|
438
|
+
Symbol.class_eval { undef :call } if call_method
|
439
|
+
yield
|
440
|
+
ensure
|
441
|
+
Symbol.instance_eval { define_method(:call, call_method) } if call_method
|
442
|
+
end
|
443
|
+
|
431
444
|
# Are all the gems required to use this command installed?
|
432
445
|
#
|
433
446
|
# @return Boolean
|
@@ -445,17 +458,28 @@ class Pry
|
|
445
458
|
|
446
459
|
private
|
447
460
|
|
461
|
+
def find_hooks(event)
|
462
|
+
event_name = "#{event}_#{command_name}"
|
463
|
+
(self.hooks || self.class.hooks).get_hooks(event_name).values
|
464
|
+
end
|
465
|
+
|
466
|
+
def before_hooks
|
467
|
+
find_hooks('before')
|
468
|
+
end
|
469
|
+
|
470
|
+
def after_hooks
|
471
|
+
find_hooks('after')
|
472
|
+
end
|
473
|
+
|
448
474
|
# Run the `#call` method and all the registered hooks.
|
449
475
|
# @param [Array<String>] args The arguments to `#call`
|
450
476
|
# @return [Object] The return value from `#call`
|
451
477
|
def call_with_hooks(*args)
|
452
|
-
|
453
|
-
instance_exec(*args, &block)
|
454
|
-
end
|
478
|
+
before_hooks.each { |block| instance_exec(*args, &block) }
|
455
479
|
|
456
480
|
ret = call(*args)
|
457
481
|
|
458
|
-
|
482
|
+
after_hooks.each do |block|
|
459
483
|
ret = instance_exec(*args, &block)
|
460
484
|
end
|
461
485
|
|
@@ -507,7 +531,7 @@ class Pry
|
|
507
531
|
# subclasses.
|
508
532
|
#
|
509
533
|
# Create subclasses using {Pry::CommandSet#create_command}, and override the
|
510
|
-
# `options(opt)` method to set up an instance of Slop, and the `process`
|
534
|
+
# `options(opt)` method to set up an instance of Pry::Slop, and the `process`
|
511
535
|
# method to actually run the command. If necessary, you can also override
|
512
536
|
# `setup` which will be called before `options`, for example to require any
|
513
537
|
# gems your command needs to run, or to set up state.
|
@@ -583,15 +607,15 @@ class Pry
|
|
583
607
|
end
|
584
608
|
end
|
585
609
|
|
586
|
-
# Return the help generated by Slop for this command.
|
610
|
+
# Return the help generated by Pry::Slop for this command.
|
587
611
|
def help
|
588
612
|
slop.help
|
589
613
|
end
|
590
614
|
|
591
|
-
# Return an instance of Slop that can parse either subcommands or the
|
615
|
+
# Return an instance of Pry::Slop that can parse either subcommands or the
|
592
616
|
# options that this command accepts.
|
593
617
|
def slop
|
594
|
-
Slop.new do |opt|
|
618
|
+
Pry::Slop.new do |opt|
|
595
619
|
opt.banner(unindent(self.class.banner))
|
596
620
|
subcommands(opt)
|
597
621
|
options(opt)
|
@@ -603,9 +627,9 @@ class Pry
|
|
603
627
|
# @param [String] search The line typed so far
|
604
628
|
# @return [Array<String>] the words to complete
|
605
629
|
def complete(search)
|
606
|
-
slop.
|
630
|
+
slop.flat_map do |opt|
|
607
631
|
[opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"]
|
608
|
-
end.
|
632
|
+
end.compact + super
|
609
633
|
end
|
610
634
|
|
611
635
|
# A method called just before `options(opt)` as part of `call`.
|
@@ -620,7 +644,7 @@ class Pry
|
|
620
644
|
# end
|
621
645
|
def setup; end
|
622
646
|
|
623
|
-
# A method to setup Slop commands so it can parse the subcommands your
|
647
|
+
# A method to setup Pry::Slop commands so it can parse the subcommands your
|
624
648
|
# command expects. If you need to set up default values, use `setup`
|
625
649
|
# instead.
|
626
650
|
#
|
@@ -655,7 +679,7 @@ class Pry
|
|
655
679
|
# end
|
656
680
|
def subcommands(cmd); end
|
657
681
|
|
658
|
-
# A method to setup Slop so it can parse the options your command expects.
|
682
|
+
# A method to setup Pry::Slop so it can parse the options your command expects.
|
659
683
|
#
|
660
684
|
# @note Please don't do anything side-effecty in the main part of this
|
661
685
|
# method, as it may be called by Pry at any time for introspection reasons.
|
@@ -672,7 +696,7 @@ class Pry
|
|
672
696
|
|
673
697
|
# The actual body of your command should go here.
|
674
698
|
#
|
675
|
-
# The `opts` mehod can be called to get the options that Slop has passed,
|
699
|
+
# The `opts` mehod can be called to get the options that Pry::Slop has passed,
|
676
700
|
# and `args` gives the remaining, unparsed arguments.
|
677
701
|
#
|
678
702
|
# The return value of this method is discarded unless the command was
|
data/lib/pry/command_set.rb
CHANGED
@@ -125,9 +125,10 @@ class Pry
|
|
125
125
|
# Pry.config.commands.before_command("whereami") do |n|
|
126
126
|
# output.puts "parameter passed was #{n}"
|
127
127
|
# end
|
128
|
+
# @deprecated Use {Pry::Hooks#add_hook} instead.
|
128
129
|
def before_command(search, &block)
|
129
130
|
cmd = find_command_by_match_or_listing(search)
|
130
|
-
cmd.hooks
|
131
|
+
cmd.hooks.add_hook("before_#{cmd.command_name}", random_hook_name, block)
|
131
132
|
end
|
132
133
|
|
133
134
|
# Execute a block of code after a command is invoked. The block also
|
@@ -139,11 +140,17 @@ class Pry
|
|
139
140
|
# Pry.config.commands.after_command("whereami") do |n|
|
140
141
|
# output.puts "command complete!"
|
141
142
|
# end
|
143
|
+
# @deprecated Use {Pry::Hooks#add_hook} instead.
|
142
144
|
def after_command(search, &block)
|
143
145
|
cmd = find_command_by_match_or_listing(search)
|
144
|
-
cmd.hooks
|
146
|
+
cmd.hooks.add_hook("after_#{cmd.command_name}", random_hook_name, block)
|
145
147
|
end
|
146
148
|
|
149
|
+
def random_hook_name
|
150
|
+
(0...8).map { ('a'..'z').to_a[rand(26)] }.join
|
151
|
+
end
|
152
|
+
private :random_hook_name
|
153
|
+
|
147
154
|
def each(&block)
|
148
155
|
@commands.each(&block)
|
149
156
|
end
|
@@ -27,16 +27,17 @@ class Pry
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def backtrace_level
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
@backtrace_level ||=
|
31
|
+
begin
|
32
|
+
bl = if opts[:ex].nil?
|
33
|
+
ex.bt_index
|
34
|
+
else
|
35
|
+
ex.bt_index = absolute_index_number(opts[:ex], ex.backtrace.size)
|
36
|
+
end
|
37
|
+
|
38
|
+
increment_backtrace_level
|
39
|
+
bl
|
40
|
+
end
|
40
41
|
end
|
41
42
|
|
42
43
|
def increment_backtrace_level
|
@@ -6,6 +6,8 @@ class Pry
|
|
6
6
|
attr_reader :_pry_
|
7
7
|
|
8
8
|
def initialize(file_with_embedded_line, _pry_, opts)
|
9
|
+
raise CommandError, "Must provide a filename, --in, or --ex." if !file_with_embedded_line
|
10
|
+
|
9
11
|
@file_with_embedded_line = file_with_embedded_line
|
10
12
|
@opts = opts
|
11
13
|
@_pry_ = _pry_
|
@@ -13,8 +15,6 @@ class Pry
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def format
|
16
|
-
raise CommandError, "Must provide a filename, --in, or --ex." if !file_with_embedded_line
|
17
|
-
|
18
18
|
set_file_and_dir_locals(file_name, _pry_, _pry_.current_context)
|
19
19
|
decorate(@code_from_file)
|
20
20
|
end
|
@@ -40,7 +40,11 @@ class Pry
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def decorate(content)
|
43
|
-
|
43
|
+
if line_number
|
44
|
+
super(content.around(line_number, code_window_size))
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
44
48
|
end
|
45
49
|
|
46
50
|
def code_type
|
@@ -51,21 +51,23 @@ class Pry
|
|
51
51
|
#
|
52
52
|
# @return [String]
|
53
53
|
def content
|
54
|
-
|
55
|
-
|
54
|
+
@content ||=
|
55
|
+
begin
|
56
|
+
raise CommandError, "Only one of --out, --in, --doc and CODE_OBJECT may be specified." if bad_option_combination?
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
content = case
|
59
|
+
when opts.present?(:o)
|
60
|
+
pry_output_content
|
61
|
+
when opts.present?(:i)
|
62
|
+
pry_input_content
|
63
|
+
when opts.present?(:d)
|
64
|
+
code_object_doc
|
65
|
+
else
|
66
|
+
code_object_source_or_file
|
67
|
+
end
|
67
68
|
|
68
|
-
|
69
|
+
restrict_to_lines(content, line_range)
|
70
|
+
end
|
69
71
|
end
|
70
72
|
|
71
73
|
# The code object
|
@@ -141,7 +143,7 @@ class Pry
|
|
141
143
|
end
|
142
144
|
|
143
145
|
def file_content
|
144
|
-
if File.
|
146
|
+
if File.exist?(obj_name)
|
145
147
|
# Set the file accessor.
|
146
148
|
self.file = obj_name
|
147
149
|
File.read(obj_name)
|
@@ -10,17 +10,17 @@ class Pry
|
|
10
10
|
end
|
11
11
|
|
12
12
|
command "get-naked", "" do
|
13
|
-
|
13
|
+
txt = %{
|
14
14
|
--
|
15
15
|
We dont have to take our clothes off to have a good time.
|
16
16
|
We could dance & party all night And drink some cherry wine.
|
17
17
|
-- Jermaine Stewart }
|
18
|
-
output.puts
|
19
|
-
|
18
|
+
output.puts txt
|
19
|
+
txt
|
20
20
|
end
|
21
21
|
|
22
22
|
command "east-coker", "" do
|
23
|
-
|
23
|
+
txt = %{
|
24
24
|
--
|
25
25
|
Now the light falls
|
26
26
|
Across the open field, leaving the deep lane
|
@@ -34,12 +34,12 @@ class Pry
|
|
34
34
|
Wait for the early owl.
|
35
35
|
-- T.S Eliot
|
36
36
|
}
|
37
|
-
output.puts
|
38
|
-
|
37
|
+
output.puts txt
|
38
|
+
txt
|
39
39
|
end
|
40
40
|
|
41
41
|
command "cohen-poem", "" do
|
42
|
-
|
42
|
+
txt = %{
|
43
43
|
--
|
44
44
|
When this American woman,
|
45
45
|
whose thighs are bound in casual red cloth,
|
@@ -57,8 +57,8 @@ class Pry
|
|
57
57
|
they are lost for hours.
|
58
58
|
-- Leonard Cohen
|
59
59
|
}
|
60
|
-
output.puts
|
61
|
-
|
60
|
+
output.puts txt
|
61
|
+
txt
|
62
62
|
end
|
63
63
|
|
64
64
|
command "pessoa-poem", "" do
|