mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
implement edit-method -p
This commit is contained in:
parent
078594ba83
commit
f19e6a9073
2 changed files with 51 additions and 22 deletions
|
@ -203,6 +203,7 @@ class Pry
|
|||
opt.on :m, :methods, "Operate on methods."
|
||||
opt.on :n, "no-reload", "Do not automatically reload the method's file after editing."
|
||||
opt.on "no-jump", "Do not fast forward editor to first line of method."
|
||||
opt.on :p, :patch, "Instead of editing the method's file, try to edit in a tempfile and apply as a monkey patch."
|
||||
opt.on :c, :context, "Select object context to run under.", true do |context|
|
||||
target = Pry.binding_for(target.eval(context))
|
||||
end
|
||||
|
@ -213,20 +214,42 @@ class Pry
|
|||
|
||||
next if opts.help?
|
||||
|
||||
if !Pry.config.editor
|
||||
output.puts "Error: No editor set!"
|
||||
output.puts "Ensure that #{text.bold("Pry.config.editor")} is set to your editor of choice."
|
||||
next
|
||||
end
|
||||
|
||||
meth_name = args.shift
|
||||
if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
|
||||
meth_name, target, type = get_method_attributes(meth_name, target, opts.to_hash(true))
|
||||
meth = get_method_object_from_target(meth_name, target, type)
|
||||
|
||||
if meth.nil?
|
||||
output.puts "Invalid method name: #{meth_name}."
|
||||
next
|
||||
end
|
||||
|
||||
next output.puts "Error: No editor set!\nEnsure that #{text.bold("Pry.config.editor")} is set to your editor of choice." if !Pry.config.editor
|
||||
if opts.p? || is_a_dynamically_defined_method?(meth)
|
||||
code, _ = code_and_code_type_for(meth)
|
||||
|
||||
lines = code.lines.to_a
|
||||
if lines[0] =~ /^def [^( \n]+/
|
||||
lines[0] = "def #{meth_name}#{$'}"
|
||||
else
|
||||
next output.puts "Error: Pry can only patch methods created with the `def` keyword."
|
||||
end
|
||||
|
||||
temp_file do |f|
|
||||
f.puts lines.join
|
||||
f.flush
|
||||
invoke_editor(f.path, 0)
|
||||
Pry.new(:input => StringIO.new(File.read(f.path))).rep(meth.owner)
|
||||
end
|
||||
next
|
||||
end
|
||||
|
||||
if is_a_c_method?(meth)
|
||||
output.puts "Error: Can't edit a C method."
|
||||
elsif is_a_dynamically_defined_method?(meth)
|
||||
output.puts "Error: Can't edit an eval method."
|
||||
|
||||
# editor is invoked here
|
||||
else
|
||||
file, line = path_line_for(meth)
|
||||
set_file_and_dir_locals(file)
|
||||
|
|
|
@ -178,37 +178,43 @@ class Pry
|
|||
[doc, code_type]
|
||||
end
|
||||
|
||||
def get_method_object(meth_name, target, options)
|
||||
def get_method_object(meth_name, target=nil, options={})
|
||||
get_method_object_from_target(*get_method_attributes(meth_name, target, options)) rescue nil
|
||||
end
|
||||
|
||||
def get_method_attributes(meth_name, target=nil, options={})
|
||||
if meth_name
|
||||
if meth_name =~ /(\S+)\#(\S+)\Z/
|
||||
context, meth_name = $1, $2
|
||||
target = Pry.binding_for(target.eval(context))
|
||||
options["instance-methods"] = true
|
||||
options[:methods] = false
|
||||
type = :instance
|
||||
elsif meth_name =~ /(\S+)\.(\S+)\Z/
|
||||
context, meth_name = $1, $2
|
||||
target = Pry.binding_for(target.eval(context))
|
||||
options["instance-methods"] = false
|
||||
options[:methods] = true
|
||||
type = :singleton
|
||||
elsif options["instance_methods"]
|
||||
type = :instance
|
||||
elsif options[:methods]
|
||||
type = :singleton
|
||||
else
|
||||
type = nil
|
||||
end
|
||||
else
|
||||
meth_name = meth_name_from_binding(target)
|
||||
type = nil
|
||||
end
|
||||
[meth_name, target, type]
|
||||
end
|
||||
|
||||
if !meth_name
|
||||
return nil
|
||||
end
|
||||
|
||||
if options["instance-methods"]
|
||||
def get_method_object_from_target(meth_name, target, type=nil)
|
||||
case type
|
||||
when :instance
|
||||
target.eval("instance_method(:#{meth_name})") rescue nil
|
||||
elsif options[:methods]
|
||||
when :singleton
|
||||
target.eval("method(:#{meth_name})") rescue nil
|
||||
else
|
||||
begin
|
||||
target.eval("instance_method(:#{meth_name})")
|
||||
rescue
|
||||
target.eval("method(:#{meth_name})") rescue nil
|
||||
end
|
||||
get_method_object_from_target(meth_name, target, :instance) ||
|
||||
get_method_object_from_target(meth_name, target, :singleton)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue