1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00

edit command: extract out ExceptionPatcher, and clean up some code

This commit is contained in:
John Mair 2012-12-31 19:13:25 +01:00
parent b1353dff1c
commit 1a6077a0f9
3 changed files with 60 additions and 44 deletions

View file

@ -8,6 +8,7 @@ class Pry
# everything (admittedly, doing extra job). # everything (admittedly, doing extra job).
class Command::Edit < Pry::ClassCommand class Command::Edit < Pry::ClassCommand
require 'pry/commands/edit/method_patcher' require 'pry/commands/edit/method_patcher'
require 'pry/commands/edit/exception_patcher'
match 'edit' match 'edit'
group 'Editing' group 'Editing'
@ -67,21 +68,21 @@ class Pry
end end
def process_local_edit def process_local_edit
content = initial_temp_file_content content = Pry::Editor.edit_tempfile_with_content(initial_temp_file_content,
initial_temp_file_content.lines.count)
if local_reload? if local_reload?
silence_warnings do silence_warnings do
eval_string.replace Pry::Editor.edit_tempfile_with_content(content, content.lines.count) eval_string.replace content
end end
end end
end end
def apply_runtime_patch def apply_runtime_patch
if patch_exception? if patch_exception?
apply_runtime_patch_to_exception ExceptionPatcher.new(self).perform_patch
else else
if code_object.is_a?(Pry::Method) if code_object.is_a?(Pry::Method)
MethodPatcher.new(code_object, target, _pry_).perform_patch MethodPatcher.new(self).perform_patch
else else
raise NotImplementedError, "Cannot yet patch #{code_object} objects!" raise NotImplementedError, "Cannot yet patch #{code_object} objects!"
end end
@ -90,6 +91,7 @@ class Pry
def process_remote_edit def process_remote_edit
file_name, line = retrieve_file_and_line file_name, line = retrieve_file_and_line
raise CommandError, "#{file_name} is not a valid file name, cannot edit!" if not_a_real_file?(file_name)
# Sanitize blanks. # Sanitize blanks.
sanitized_file_name = Shellwords.escape(file_name) sanitized_file_name = Shellwords.escape(file_name)
@ -122,7 +124,11 @@ class Pry
code_object.dynamically_defined? code_object.dynamically_defined?
end end
def retrieve_input_expression def patch_exception?
opts.present?(:ex) && opts.present?(:patch)
end
def input_expression
case opts[:i] case opts[:i]
when Range when Range
(_pry_.input_array[opts[:i]] || []).join (_pry_.input_array[opts[:i]] || []).join
@ -155,11 +161,11 @@ class Pry
when opts.present?(:temp) when opts.present?(:temp)
"" ""
when opts.present?(:in) when opts.present?(:in)
retrieve_input_expression input_expression
when eval_string.strip != "" when eval_string.strip != ""
eval_string eval_string
else else
_pry_.input_array.reverse_each.find{ |x| x && x.strip != "" } || "" _pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || ""
end end
end end
@ -168,6 +174,18 @@ class Pry
str =~ /\/|\\/ str =~ /\/|\\/
end end
def retrieve_file_and_line
file_name, line = if opts.present?(:ex)
file_and_line_for_exception
elsif opts.present?(:current)
current_file_and_line
else
object_file_and_line
end
[file_name, opts.present?(:line) ? opts[:l].to_i : line]
end
def file_and_line_for_exception def file_and_line_for_exception
raise CommandError, "No exception found." if _pry_.last_exception.nil? raise CommandError, "No exception found." if _pry_.last_exception.nil?
@ -194,35 +212,6 @@ class Pry
[file_name, line] [file_name, line]
end end
end end
def retrieve_file_and_line
file_name, line = if opts.present?(:ex)
file_and_line_for_exception
elsif opts.present?(:current)
current_file_and_line
else
object_file_and_line
end
if not_a_real_file?(file_name)
raise CommandError, "#{file_name} is not a valid file name, cannot edit!"
end
[file_name, opts.present?(:line) ? opts[:l].to_i : line]
end
def patch_exception?
opts.present?(:ex) && opts.present?(:patch)
end
def apply_runtime_patch_to_exception
file_name, line = file_and_line_for_exception
lines = state.dynamical_ex_file || File.read(file_name)
source = Pry::Editor.edit_tempfile_with_content(lines)
_pry_.evaluate_ruby source
state.dynamical_ex_file = source.split("\n")
end
end end
Pry::Commands.add_command(Pry::Command::Edit) Pry::Commands.add_command(Pry::Command::Edit)

View file

@ -0,0 +1,21 @@
class Pry
class Command::Edit
class ExceptionPatcher
attr_accessor :edit_context
def initialize(edit_context)
@edit_context = edit_context
end
# perform the patch
def perform_patch
file_name, line = edit_context.retrieve_file_and_line
lines = edit_context.state.dynamical_ex_file || File.read(file_name)
source = Pry::Editor.edit_tempfile_with_content(lines)
edit_context._pry_.evaluate_ruby source
edit_context.state.dynamical_ex_file = source.split("\n")
end
end
end
end

View file

@ -5,17 +5,15 @@ class Pry
attr_accessor :target attr_accessor :target
attr_accessor :_pry_ attr_accessor :_pry_
def initialize(method_object, target, _pry_) def initialize(edit_context)
@method_object = method_object @method_object = edit_context.code_object
@target = target @target = edit_context.target
@_pry_ = _pry_ @_pry_ = edit_context._pry_
end end
# perform the patch # perform the patch
def perform_patch def perform_patch
lines = method_object.source.lines.to_a source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(adjusted_lines)))
lines[0] = definition_line_for_owner(lines[0])
source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(lines)))
if method_object.alias? if method_object.alias?
with_method_transaction do with_method_transaction do
@ -29,6 +27,14 @@ class Pry
private private
# The method code adjusted so that the first line is rewritten
# so that def self.foo --> def foo
def adjusted_lines
lines = method_object.source.lines.to_a
lines[0] = definition_line_for_owner(lines.first)
lines
end
# Run some code ensuring that at the end target#meth_name will not have changed. # Run some code ensuring that at the end target#meth_name will not have changed.
# #
# When we're redefining aliased methods we will overwrite the method at the # When we're redefining aliased methods we will overwrite the method at the