Skip to content

Commit

Permalink
edit command: extract out ExceptionPatcher, and clean up some code
Browse files Browse the repository at this point in the history
  • Loading branch information
banister committed Dec 31, 2012
1 parent b1353df commit 1a6077a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 44 deletions.
63 changes: 26 additions & 37 deletions lib/pry/commands/edit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class Pry
# everything (admittedly, doing extra job).
class Command::Edit < Pry::ClassCommand
require 'pry/commands/edit/method_patcher'
require 'pry/commands/edit/exception_patcher'

match 'edit'
group 'Editing'
Expand Down Expand Up @@ -67,21 +68,21 @@ def process
end

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?
silence_warnings do
eval_string.replace Pry::Editor.edit_tempfile_with_content(content, content.lines.count)
eval_string.replace content
end
end
end

def apply_runtime_patch
if patch_exception?
apply_runtime_patch_to_exception
ExceptionPatcher.new(self).perform_patch
else
if code_object.is_a?(Pry::Method)
MethodPatcher.new(code_object, target, _pry_).perform_patch
MethodPatcher.new(self).perform_patch
else
raise NotImplementedError, "Cannot yet patch #{code_object} objects!"
end
Expand All @@ -90,6 +91,7 @@ def apply_runtime_patch

def process_remote_edit
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.
sanitized_file_name = Shellwords.escape(file_name)
Expand Down Expand Up @@ -122,7 +124,11 @@ def dynamically_defined_method?
code_object.dynamically_defined?
end

def retrieve_input_expression
def patch_exception?
opts.present?(:ex) && opts.present?(:patch)
end

def input_expression
case opts[:i]
when Range
(_pry_.input_array[opts[:i]] || []).join
Expand Down Expand Up @@ -155,11 +161,11 @@ def initial_temp_file_content
when opts.present?(:temp)
""
when opts.present?(:in)
retrieve_input_expression
input_expression
when eval_string.strip != ""
eval_string
else
_pry_.input_array.reverse_each.find{ |x| x && x.strip != "" } || ""
_pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || ""
end
end

Expand All @@ -168,6 +174,18 @@ def probably_a_file?(str)
str =~ /\/|\\/
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
raise CommandError, "No exception found." if _pry_.last_exception.nil?

Expand All @@ -194,35 +212,6 @@ def object_file_and_line
[file_name, line]
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

Pry::Commands.add_command(Pry::Command::Edit)
Expand Down
21 changes: 21 additions & 0 deletions lib/pry/commands/edit/exception_patcher.rb
Original file line number Diff line number Diff line change
@@ -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
20 changes: 13 additions & 7 deletions lib/pry/commands/edit/method_patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@ class MethodPatcher
attr_accessor :target
attr_accessor :_pry_

def initialize(method_object, target, _pry_)
@method_object = method_object
@target = target
@_pry_ = _pry_
def initialize(edit_context)
@method_object = edit_context.code_object
@target = edit_context.target
@_pry_ = edit_context._pry_
end

# perform the patch
def perform_patch
lines = method_object.source.lines.to_a
lines[0] = definition_line_for_owner(lines[0])
source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(lines)))
source = wrap_for_nesting(wrap_for_owner(Pry::Editor.edit_tempfile_with_content(adjusted_lines)))

if method_object.alias?
with_method_transaction do
Expand All @@ -29,6 +27,14 @@ def perform_patch

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.
#
# When we're redefining aliased methods we will overwrite the method at the
Expand Down

0 comments on commit 1a6077a

Please sign in to comment.