pry 0.9.8pre5-i386-mswin32 → 0.9.8pre6-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.
- data/.gitignore +1 -0
- data/CHANGELOG +36 -0
- data/Rakefile +2 -2
- data/lib/pry.rb +3 -2
- data/lib/pry/code.rb +344 -0
- data/lib/pry/command.rb +22 -21
- data/lib/pry/command_set.rb +28 -15
- data/lib/pry/commands.rb +0 -1
- data/lib/pry/config.rb +2 -2
- data/lib/pry/default_commands/context.rb +100 -86
- data/lib/pry/default_commands/documentation.rb +20 -1
- data/lib/pry/default_commands/gems.rb +65 -37
- data/lib/pry/default_commands/input.rb +107 -154
- data/lib/pry/default_commands/introspection.rb +154 -102
- data/lib/pry/default_commands/shell.rb +89 -91
- data/lib/pry/helpers/command_helpers.rb +14 -76
- data/lib/pry/hooks.rb +12 -1
- data/lib/pry/pry_class.rb +3 -3
- data/lib/pry/pry_instance.rb +40 -15
- data/lib/pry/version.rb +1 -1
- data/pry.gemspec +16 -16
- data/test/helper.rb +9 -23
- data/test/test_code.rb +201 -0
- data/test/test_command.rb +10 -0
- data/test/test_default_commands/test_input.rb +11 -11
- data/test/test_default_commands/test_introspection.rb +5 -5
- data/test/test_default_commands/test_shell.rb +10 -10
- data/test/test_hooks.rb +36 -0
- metadata +19 -17
- data/lib/pry/extended_commands/user_command_api.rb +0 -122
@@ -9,9 +9,10 @@ class Pry
|
|
9
9
|
end
|
10
10
|
|
11
11
|
command "show-input", "Show the contents of the input buffer for the current multi-line expression." do
|
12
|
-
|
12
|
+
output.puts Code.new(eval_string).with_line_numbers
|
13
13
|
end
|
14
14
|
|
15
|
+
# TODO: refactor to command_class
|
15
16
|
command(/amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/, "Amend a line of input in multi-line mode. Type `amend-line --help` for more information. Aliases %",
|
16
17
|
:interpolate => false, :listing => "amend-line") do |*args|
|
17
18
|
start_line_number, end_line_number, replacement_line = *args
|
@@ -59,35 +60,54 @@ class Pry
|
|
59
60
|
|
60
61
|
alias_command(/%.?(-?\d+)?(?:\.\.(-?\d+))?/, "amend-line")
|
61
62
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
command_class "play" do
|
64
|
+
description "Play back a string variable or a method or a file as input. Type `play --help` for more information."
|
65
|
+
|
66
|
+
banner <<-BANNER
|
67
|
+
Usage: play [OPTIONS] [--help]
|
68
|
+
|
69
|
+
The play command enables you to replay code from files and methods as
|
70
|
+
if they were entered directly in the Pry REPL. Default action (no
|
71
|
+
options) is to play the provided string variable
|
71
72
|
|
73
|
+
e.g: `play _in_[20] --lines 1..3`
|
74
|
+
e.g: `play -m Pry#repl --lines 1..-1`
|
75
|
+
e.g: `play -f Rakefile --lines 5`
|
76
|
+
|
77
|
+
https://github.com/pry/pry/wiki/User-Input#wiki-Play
|
78
|
+
BANNER
|
79
|
+
|
80
|
+
def options(opt)
|
72
81
|
opt.on :l, :lines, 'The line (or range of lines) to replay.', true, :as => Range
|
73
82
|
opt.on :m, :method, 'Play a method.', true
|
74
83
|
opt.on :f, "file", 'The file to replay in context.', true
|
75
84
|
opt.on :o, "open", 'When used with the -m switch, it plays the entire method except the last line, leaving the method definition "open". `amend-line` can then be used to modify the method.'
|
76
|
-
|
77
|
-
|
85
|
+
end
|
86
|
+
|
87
|
+
def process
|
88
|
+
if opts.present?(:method)
|
89
|
+
process_method
|
90
|
+
elsif opts.present?(:file)
|
91
|
+
process_file
|
92
|
+
else
|
93
|
+
process_input
|
78
94
|
end
|
95
|
+
|
96
|
+
run "show-input" unless _pry_.complete_expression?(eval_string)
|
79
97
|
end
|
80
98
|
|
81
|
-
|
99
|
+
def process_method
|
82
100
|
meth_name = opts[:m]
|
83
101
|
meth = get_method_or_raise(meth_name, target, {}, :omit_help)
|
84
|
-
|
102
|
+
return unless meth.source
|
85
103
|
|
86
104
|
range = opts.present?(:lines) ? one_index_range_or_number(opts[:l]) : (0..-1)
|
87
105
|
range = (0..-2) if opts.present?(:open)
|
88
106
|
|
89
107
|
eval_string << Array(meth.source.each_line.to_a[range]).join
|
90
|
-
|
108
|
+
end
|
109
|
+
|
110
|
+
def process_file
|
91
111
|
file_name = File.expand_path(opts[:f])
|
92
112
|
|
93
113
|
if !File.exists?(file_name)
|
@@ -98,9 +118,10 @@ class Pry
|
|
98
118
|
range = opts.present?(:lines) ? one_index_range_or_number(opts[:l]) : (0..-1)
|
99
119
|
range = (0..-2) if opts.present?(:open)
|
100
120
|
|
101
|
-
|
102
|
-
|
103
|
-
|
121
|
+
eval_string << Array(text_array[range]).join
|
122
|
+
end
|
123
|
+
|
124
|
+
def process_input
|
104
125
|
if !args.first
|
105
126
|
raise CommandError, "No input to play command."
|
106
127
|
end
|
@@ -113,177 +134,109 @@ class Pry
|
|
113
134
|
eval_string << Array(code.each_line.to_a[range]).join
|
114
135
|
end
|
115
136
|
|
116
|
-
run "show-input" if !_pry_.complete_expression?(eval_string)
|
117
137
|
end
|
118
138
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
opt.on :
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
opt.on
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
opt.on :
|
143
|
-
|
144
|
-
opt.on :r, :replay, 'The line (or range of lines) to replay.', true,
|
145
|
-
:as => Range
|
146
|
-
|
147
|
-
opt.on "save", "Save history to a file. --save [start..end] output.txt. Pry commands are excluded from saved history.", true,
|
148
|
-
:as => Range
|
149
|
-
|
150
|
-
opt.on :c, :clear, 'Clear the history.', :unless => :grep
|
151
|
-
|
152
|
-
opt.on :h, :help, 'Show this message.', :tail => true, :unless => :grep do
|
153
|
-
output.puts opt.help
|
154
|
-
end
|
139
|
+
command_class "hist", "Show and replay Readline history. Aliases: history" do
|
140
|
+
banner <<-USAGE
|
141
|
+
Usage: hist
|
142
|
+
hist --head N
|
143
|
+
hist --tail N
|
144
|
+
hist --show START..END
|
145
|
+
hist --grep PATTERN
|
146
|
+
hist --clear
|
147
|
+
hist --replay START..END
|
148
|
+
hist --save [START..END] FILE
|
149
|
+
USAGE
|
150
|
+
|
151
|
+
def options(opt)
|
152
|
+
opt.on :h, :head, "Display the first N items.", :optional => true, :as => Integer
|
153
|
+
opt.on :t, :tail, "Display the last N items.", :optional => true, :as => Integer
|
154
|
+
opt.on :s, :show, "Show the given range of lines.", :optional => true, :as => Range
|
155
|
+
opt.on :g, :grep, "Show lines matching the given pattern.", true, :as => String
|
156
|
+
opt.on :c, :clear, "Clear the current session's history."
|
157
|
+
opt.on :r, :replay, "Replay a line or range of lines.", true, :as => Range
|
158
|
+
opt.on :save, "Save history to a file.", true, :as => Range
|
159
|
+
|
160
|
+
opt.on :e, :'exclude-pry', "Exclude Pry commands from the history."
|
161
|
+
opt.on :n, :'no-numbers', "Omit line numbers."
|
162
|
+
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
155
163
|
end
|
156
|
-
next if opts.present?(:help)
|
157
164
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
165
|
+
def process
|
166
|
+
@history = Pry::Code(Pry.history.to_a)
|
167
|
+
|
168
|
+
@history = case
|
169
|
+
when opts.present?(:head)
|
170
|
+
@history.between(1, opts[:head] || 10)
|
171
|
+
when opts.present?(:tail)
|
172
|
+
@history.between(-(opts[:tail] || 10), -1)
|
173
|
+
when opts.present?(:show)
|
174
|
+
@history.between(opts[:show])
|
175
|
+
else
|
176
|
+
@history
|
169
177
|
end
|
170
|
-
end
|
171
|
-
|
172
|
-
stagger_output history.compact.join "\n"
|
173
|
-
next
|
174
|
-
end
|
175
178
|
|
176
|
-
|
177
|
-
|
178
|
-
list = history.first limit
|
179
|
-
lines = list.join("\n")
|
180
|
-
if opts.present?(:"no-numbers")
|
181
|
-
stagger_output lines
|
182
|
-
else
|
183
|
-
stagger_output text.with_line_numbers(lines, 0)
|
179
|
+
if opts.present?(:grep)
|
180
|
+
@history = @history.grep(opts[:grep])
|
184
181
|
end
|
185
|
-
next
|
186
|
-
end
|
187
182
|
|
188
|
-
|
189
|
-
|
190
|
-
offset = history.size - limit
|
191
|
-
offset = offset < 0 ? 0 : offset
|
192
|
-
|
193
|
-
list = history.last limit
|
194
|
-
lines = list.join("\n")
|
195
|
-
if opts.present?(:'no-numbers')
|
196
|
-
stagger_output lines
|
197
|
-
else
|
198
|
-
stagger_output text.with_line_numbers(lines, offset)
|
183
|
+
if opts.present?(:'exclude-pry')
|
184
|
+
@history = @history.select { |l, ln| !command_set.valid_command?(l) }
|
199
185
|
end
|
200
|
-
next
|
201
|
-
end
|
202
186
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
187
|
+
if opts.present?(:save)
|
188
|
+
process_save
|
189
|
+
elsif opts.present?(:clear)
|
190
|
+
process_clear
|
191
|
+
elsif opts.present?(:replay)
|
192
|
+
process_replay
|
209
193
|
else
|
210
|
-
|
194
|
+
process_display
|
211
195
|
end
|
212
|
-
next
|
213
196
|
end
|
214
197
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
if opts.present?(:'no-numbers')
|
219
|
-
element
|
220
|
-
else
|
221
|
-
"#{text.blue index}: #{element}"
|
222
|
-
end
|
223
|
-
end
|
198
|
+
def process_display
|
199
|
+
unless opts.present?(:'no-numbers')
|
200
|
+
@history = @history.with_line_numbers
|
224
201
|
end
|
225
|
-
stagger_output history.compact.join "\n"
|
226
|
-
next
|
227
|
-
end
|
228
202
|
|
229
|
-
|
230
|
-
range = opts['replay']
|
231
|
-
actions = Array(history[range]).join("\n") + "\n"
|
232
|
-
_pry_.input_stack << _pry_.input
|
233
|
-
_pry_.input = StringIO.new(actions)
|
234
|
-
next
|
235
|
-
end
|
236
|
-
|
237
|
-
if opts.present?(:clear)
|
238
|
-
Pry.history.clear
|
239
|
-
output.puts 'History cleared.'
|
240
|
-
next
|
203
|
+
render_output(@history, opts)
|
241
204
|
end
|
242
205
|
|
243
|
-
|
244
|
-
|
245
|
-
file_name = nil
|
246
|
-
hist_array = nil
|
247
|
-
|
248
|
-
case opts["save"]
|
206
|
+
def process_save
|
207
|
+
case opts[:save]
|
249
208
|
when Range
|
250
|
-
|
209
|
+
@history = @history.between(opts[:save])
|
251
210
|
|
252
|
-
|
211
|
+
unless args.first
|
253
212
|
raise CommandError, "Must provide a file name."
|
254
213
|
end
|
255
214
|
|
256
215
|
file_name = File.expand_path(args.first)
|
257
216
|
when String
|
258
|
-
|
259
|
-
file_name = File.expand_path(opts["save"])
|
217
|
+
file_name = File.expand_path(opts[:save])
|
260
218
|
end
|
261
219
|
|
262
|
-
output.puts "Saving history in #{file_name}
|
263
|
-
# exclude pry commands
|
264
|
-
hist_array.reject! do |element|
|
265
|
-
command_set.valid_command?(element)
|
266
|
-
end
|
220
|
+
output.puts "Saving history in #{file_name}..."
|
267
221
|
|
268
|
-
File.open(file_name, 'w')
|
269
|
-
f.write hist_array.join("\n")
|
270
|
-
end
|
222
|
+
File.open(file_name, 'w') { |f| f.write(@history.to_s) }
|
271
223
|
|
272
|
-
output.puts "
|
273
|
-
next
|
224
|
+
output.puts "History saved."
|
274
225
|
end
|
275
226
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
227
|
+
def process_clear
|
228
|
+
Pry.history.clear
|
229
|
+
output.puts "History cleared."
|
230
|
+
end
|
231
|
+
|
232
|
+
def process_replay
|
233
|
+
@history = @history.between(opts[:r])
|
234
|
+
_pry_.input_stack << _pry_.input
|
235
|
+
_pry_.input = StringIO.new(@history.to_s)
|
281
236
|
end
|
282
237
|
end
|
283
238
|
|
284
239
|
alias_command "history", "hist"
|
285
|
-
|
286
240
|
end
|
287
|
-
|
288
241
|
end
|
289
242
|
end
|
@@ -5,13 +5,26 @@ class Pry
|
|
5
5
|
|
6
6
|
Introspection = Pry::CommandSet.new do
|
7
7
|
|
8
|
-
command_class "show-method"
|
8
|
+
command_class "show-method" do
|
9
|
+
description "Show the source for METH. Type `show-method --help` for more info. Aliases: $, show-source"
|
10
|
+
|
9
11
|
banner <<-BANNER
|
10
12
|
Usage: show-method [OPTIONS] [METH]
|
13
|
+
Aliases: $, show-source
|
14
|
+
|
11
15
|
Show the source for method METH. Tries instance methods first and then methods by default.
|
12
|
-
|
16
|
+
|
17
|
+
e.g: `show-method hello_method`
|
18
|
+
e.g: `show-method -m hello_method`
|
19
|
+
e.g: `show-method Pry#rep`
|
20
|
+
|
21
|
+
https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method
|
13
22
|
BANNER
|
14
23
|
|
24
|
+
command_options(
|
25
|
+
:shellwords => false
|
26
|
+
)
|
27
|
+
|
15
28
|
def options(opt)
|
16
29
|
method_options(opt)
|
17
30
|
opt.on :l, "line-numbers", "Show line numbers."
|
@@ -28,20 +41,16 @@ class Pry
|
|
28
41
|
output.puts "#{text.bold("Visibility:")} #{meth.visibility}"
|
29
42
|
output.puts
|
30
43
|
|
31
|
-
if Pry.color
|
32
|
-
code = CodeRay.scan(meth.source, meth.source_type).term
|
33
|
-
else
|
34
|
-
code = meth.source
|
35
|
-
end
|
36
|
-
|
37
|
-
start_line = false
|
38
44
|
if opts.present?(:'base-one')
|
39
45
|
start_line = 1
|
40
|
-
|
46
|
+
else
|
41
47
|
start_line = meth.source_line || 1
|
42
48
|
end
|
43
49
|
|
44
|
-
|
50
|
+
code = Code.from_method(meth, start_line).
|
51
|
+
with_line_numbers(opts.present?(:b) || opts.present?(:l))
|
52
|
+
|
53
|
+
render_output(code, opts)
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
@@ -81,68 +90,75 @@ class Pry
|
|
81
90
|
output.puts make_header(block)
|
82
91
|
output.puts
|
83
92
|
|
84
|
-
|
85
|
-
code = CodeRay.scan(block.source, :ruby).term
|
86
|
-
else
|
87
|
-
code = block.source
|
88
|
-
end
|
93
|
+
code = Code.from_method(block).with_line_numbers(opts.present?(:'line-numbers'))
|
89
94
|
|
90
|
-
|
91
|
-
if opts.present?(:'line-numbers')
|
92
|
-
start_line = block.source_line || 1
|
93
|
-
end
|
94
|
-
|
95
|
-
render_output(opts.present?(:flood), opts.present?(:'line-numbers') ? block.source_line : false, code)
|
96
|
-
code
|
95
|
+
render_output(code, opts)
|
97
96
|
else
|
98
97
|
raise CommandError, "No such command: #{command_name}."
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
Ensure #{text.bold("Pry.config.editor")} is set to your editor of choice.
|
108
|
-
e.g: edit sample.rb
|
109
|
-
USAGE
|
101
|
+
command_class "edit" do
|
102
|
+
description "Invoke the default editor on a file. Type `edit --help` for more info"
|
103
|
+
|
104
|
+
banner <<-BANNER
|
105
|
+
Usage: edit [--no-reload|--reload] [--line LINE] [--temp|--ex|FILE[:LINE]|--in N]
|
110
106
|
|
107
|
+
Open a text editor. When no FILE is given, edits the pry input buffer.
|
108
|
+
Ensure Pry.config.editor is set to your editor of choice.
|
109
|
+
|
110
|
+
e.g: `edit sample.rb`
|
111
|
+
e.g: `edit sample.rb --line 105`
|
112
|
+
e.g: `edit --ex`
|
113
|
+
|
114
|
+
https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_command
|
115
|
+
BANNER
|
116
|
+
|
117
|
+
def options(opt)
|
111
118
|
opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)", :optional => true, :as => Integer
|
112
119
|
opt.on :i, :in, "Open a temporary file containing the Nth line of _in_. N may be a range.", :optional => true, :as => Range, :default => -1..-1
|
113
120
|
opt.on :t, :temp, "Open an empty temporary file"
|
114
121
|
opt.on :l, :line, "Jump to this line in the opened file", true, :as => Integer
|
115
122
|
opt.on :n, :"no-reload", "Don't automatically reload the edited code"
|
116
123
|
opt.on :r, :reload, "Reload the edited code immediately (default for ruby files)"
|
117
|
-
|
118
|
-
|
124
|
+
end
|
125
|
+
|
126
|
+
def process
|
127
|
+
if [opts.present?(:ex), opts.present?(:temp), opts.present?(:in), !args.empty?].count(true) > 1
|
128
|
+
raise CommandError, "Only one of --ex, --temp, --in and FILE may be specified."
|
129
|
+
end
|
130
|
+
|
131
|
+
if !opts.present?(:ex) && args.empty?
|
132
|
+
# edit of local code, eval'd within pry.
|
133
|
+
process_local_edit
|
134
|
+
else
|
135
|
+
# edit of remote code, eval'd at top-level
|
136
|
+
process_remote_edit
|
119
137
|
end
|
120
138
|
end
|
121
|
-
next if opts.present?(:help)
|
122
139
|
|
123
|
-
|
124
|
-
|
140
|
+
def process_i
|
141
|
+
case opts[:i]
|
142
|
+
when Range
|
143
|
+
(_pry_.input_array[opts[:i]] || []).join
|
144
|
+
when Fixnum
|
145
|
+
_pry_.input_array[opts[:i]] || ""
|
146
|
+
else
|
147
|
+
return output.puts "Not a valid range: #{opts[:i]}"
|
148
|
+
end
|
125
149
|
end
|
126
150
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
next output.puts "Not a valid range: #{opts[:i]}"
|
140
|
-
end
|
141
|
-
elsif eval_string.strip != ""
|
142
|
-
eval_string
|
143
|
-
else
|
144
|
-
_pry_.input_array.reverse_each.find{ |x| x && x.strip != "" } || ""
|
145
|
-
end
|
151
|
+
def process_local_edit
|
152
|
+
content = case
|
153
|
+
when opts.present?(:temp)
|
154
|
+
""
|
155
|
+
when opts.present?(:in)
|
156
|
+
process_i
|
157
|
+
when eval_string.strip != ""
|
158
|
+
eval_string
|
159
|
+
else
|
160
|
+
_pry_.input_array.reverse_each.find{ |x| x && x.strip != "" } || ""
|
161
|
+
end
|
146
162
|
|
147
163
|
line = content.lines.count
|
148
164
|
|
@@ -156,9 +172,9 @@ class Pry
|
|
156
172
|
end
|
157
173
|
end
|
158
174
|
end
|
175
|
+
end
|
159
176
|
|
160
|
-
|
161
|
-
else
|
177
|
+
def process_remote_edit
|
162
178
|
if opts.present?(:ex)
|
163
179
|
if _pry_.last_exception.nil?
|
164
180
|
raise CommandError, "No exception found."
|
@@ -203,15 +219,25 @@ class Pry
|
|
203
219
|
end
|
204
220
|
end
|
205
221
|
|
206
|
-
command_class "edit-method"
|
222
|
+
command_class "edit-method" do
|
223
|
+
description "Edit a method. Type `edit-method --help` for more info."
|
224
|
+
|
225
|
+
banner <<-BANNER
|
226
|
+
Usage: edit-method [OPTIONS] [METH]
|
227
|
+
|
228
|
+
Edit the method METH in an editor.
|
229
|
+
Ensure Pry.config.editor is set to your editor of choice.
|
230
|
+
|
231
|
+
e.g: `edit-method hello_method`
|
232
|
+
e.g: `edit-method Pry#rep`
|
233
|
+
e.g: `edit-method`
|
234
|
+
|
235
|
+
https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_method
|
236
|
+
BANNER
|
237
|
+
|
238
|
+
command_options :shellwords => false
|
207
239
|
|
208
240
|
def options(opt)
|
209
|
-
opt.banner unindent <<-BANNER
|
210
|
-
Usage: edit-method [OPTIONS] [METH]
|
211
|
-
Edit the method METH in an editor.
|
212
|
-
Ensure #{text.bold("Pry.config.editor")} is set to your editor of choice.
|
213
|
-
e.g: edit-method hello_method
|
214
|
-
BANNER
|
215
241
|
method_options(opt)
|
216
242
|
opt.on :n, "no-reload", "Do not automatically reload the method's file after editing."
|
217
243
|
opt.on "no-jump", "Do not fast forward editor to first line of method."
|
@@ -219,62 +245,88 @@ class Pry
|
|
219
245
|
end
|
220
246
|
|
221
247
|
def process
|
222
|
-
meth = method_object
|
223
248
|
if !Pry.config.editor
|
224
249
|
raise CommandError, "No editor set!\nEnsure that #{text.bold("Pry.config.editor")} is set to your editor of choice."
|
225
250
|
end
|
226
251
|
|
227
|
-
|
228
|
-
|
252
|
+
begin
|
253
|
+
@method = method_object
|
254
|
+
rescue NonMethodContextError => err
|
255
|
+
end
|
229
256
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
else
|
234
|
-
raise CommandError, "Pry can only patch methods created with the `def` keyword."
|
257
|
+
if opts.present?(:patch) || (@method && @method.dynamically_defined?)
|
258
|
+
if err
|
259
|
+
raise err # can't patch a non-method
|
235
260
|
end
|
236
261
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
if meth.alias?
|
243
|
-
with_method_transaction(original_name, meth.owner) do
|
244
|
-
Pry.new(:input => StringIO.new(File.read(f.path))).rep(meth.owner)
|
245
|
-
Pry.binding_for(meth.owner).eval("alias #{meth.name} #{original_name}")
|
246
|
-
end
|
247
|
-
else
|
248
|
-
Pry.new(:input => StringIO.new(File.read(f.path))).rep(meth.owner)
|
249
|
-
end
|
262
|
+
process_patch
|
263
|
+
else
|
264
|
+
if err && !File.exist?(target.eval('__FILE__'))
|
265
|
+
raise err # can't edit a non-file
|
250
266
|
end
|
251
|
-
|
267
|
+
|
268
|
+
process_file
|
252
269
|
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def process_patch
|
273
|
+
lines = @method.source.lines.to_a
|
253
274
|
|
254
|
-
if
|
255
|
-
|
275
|
+
if ((original_name = @method.original_name) &&
|
276
|
+
lines[0] =~ /^def (?:.*?\.)?#{original_name}(?=[\(\s;]|$)/)
|
277
|
+
lines[0] = "def #{original_name}#{$'}"
|
256
278
|
else
|
257
|
-
|
279
|
+
raise CommandError, "Pry can only patch methods created with the `def` keyword."
|
280
|
+
end
|
258
281
|
|
259
|
-
|
260
|
-
|
261
|
-
|
282
|
+
temp_file do |f|
|
283
|
+
f.puts lines.join
|
284
|
+
f.flush
|
285
|
+
invoke_editor(f.path, 0)
|
286
|
+
|
287
|
+
if @method.alias?
|
288
|
+
with_method_transaction(original_name, @method.owner) do
|
289
|
+
Pry.new(:input => StringIO.new(File.read(f.path))).rep(@method.owner)
|
290
|
+
Pry.binding_for(@method.owner).eval("alias #{@method.name} #{original_name}")
|
291
|
+
end
|
292
|
+
else
|
293
|
+
Pry.new(:input => StringIO.new(File.read(f.path))).rep(@method.owner)
|
262
294
|
end
|
263
295
|
end
|
264
296
|
end
|
265
|
-
end
|
266
297
|
|
267
|
-
|
268
|
-
|
269
|
-
target = Pry.binding_for(target)
|
270
|
-
temp_name = "__pry_#{meth_name}__"
|
298
|
+
def process_file
|
299
|
+
file, line = extract_file_and_line
|
271
300
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
target.eval("undef #{temp_name}") rescue nil
|
301
|
+
invoke_editor(file, opts["no-jump"] ? 0 : line)
|
302
|
+
silence_warnings do
|
303
|
+
load file unless opts.present?(:'no-jump') || Pry.config.disable_auto_reload
|
304
|
+
end
|
277
305
|
end
|
306
|
+
|
307
|
+
protected
|
308
|
+
def extract_file_and_line
|
309
|
+
if @method
|
310
|
+
if @method.source_type == :c
|
311
|
+
raise CommandError, "Can't edit a C method."
|
312
|
+
else
|
313
|
+
[@method.source_file, @method.source_line]
|
314
|
+
end
|
315
|
+
else
|
316
|
+
[target.eval('__FILE__'), target.eval('__LINE__')]
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def with_method_transaction(meth_name, target=TOPLEVEL_BINDING)
|
321
|
+
target = Pry.binding_for(target)
|
322
|
+
temp_name = "__pry_#{meth_name}__"
|
323
|
+
|
324
|
+
target.eval("alias #{temp_name} #{meth_name}")
|
325
|
+
yield
|
326
|
+
target.eval("alias #{meth_name} #{temp_name}")
|
327
|
+
ensure
|
328
|
+
target.eval("undef #{temp_name}") rescue nil
|
329
|
+
end
|
278
330
|
end
|
279
331
|
end
|
280
332
|
end
|