Skip to content

Instantly share code, notes, and snippets.

@swarley
Created March 31, 2012 07:39
Show Gist options
  • Save swarley/2260528 to your computer and use it in GitHub Desktop.
Save swarley/2260528 to your computer and use it in GitHub Desktop.
Pry::Commands.create_command "find-method" do
description "find-method"
def options(opti)
opti.on :n, :name, "Search for a method by name"
opti.on :c, :content, "Search for a method based on content in Regex form"
end
def process
return if args.size < 1
pattern = eval "/#{args[0]}/"
if args[1]
klass = ::Kernel.eval "::#{args[1]}"
else
puts target_self_eval(pattern, opts)
return
end
if opts.name?
puts name_search(pattern, klass)
elsif opts.content?
puts content_search(pattern, klass)
else
puts name_search(pattern, klass)
end
end
private
def puts(item)
output.puts item
end
def target_self_eval(pattern, opts)
obj = target_self
if opts.name?
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
elsif opts.content?
ret = []
obj.methods.select do |x|
meth = Pry::Method.new obj.method(x)
next if meth.alias?
if meth.source =~ pattern
ret << "(#{obj.to_s})##{x}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
end
return ret
else
return (obj.methods.select {|x| x=~pattern}).map {|x| "(#{obj.to_s})##{x}" }
end
end
def content_search(pattern, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(klass.instance_methods - [:__id__]).each do |method_name|
begin
meth = Pry::Method.new(klass.instance_method(method_name))
if meth.source =~ pattern && !meth.alias?
meths << "#{klass}##{method_name}: " + (meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n\t")
end
rescue Exception
next
end
end
klass.constants.each do |klazz|
meths += ((res = content_search(pattern, klass.const_get(klazz), current)) ? res : [])
end
return meths.flatten
end
def name_search(regex, klass, current=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(klass.instance_methods + klass.methods).uniq.each {|x| meths << "#{klass}##{x}" if x.to_s =~ regex }
klass.constants.each do |x|
meths += ((res = name_search(regex, klass.const_get(x), current)) ? res : [])
end
return meths.flatten
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment