pry 0.9.8pre5-i386-mingw32 → 0.9.8pre6-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|