Skip to content

Instantly share code, notes, and snippets.

@drusepth
Last active January 5, 2023 20:55
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save drusepth/48a246e1263183e0418c to your computer and use it in GitHub Desktop.
require 'google-search'
require 'thread'
require 'nokogiri'
require 'open-uri'
CASCADE_SNIPPETS = false
def method_missing method_name, *args, &block
result_queue = Queue.new
google_thread = Thread.new do
puts "Searching new method for #{method_name}"
Google::Search::Web.new(:query => "ruby #{method_name} site:stackoverflow.com").each do |result|
result_queue << result.uri
end
end
active_threads = []
code_snippets = Queue.new
loop do
google_thread.join if result_queue.empty?
break if result_queue.empty?
uri = result_queue.pop 0
active_threads << Thread.new do
puts "Fetching HTML content for #{uri}"
html = Nokogiri::HTML(open uri)
code_snippets << html.css('pre.lang-rb').map(&:text)
code_snippets.flatten!
end
end
loop do
active_threads.reject! { |t| !t.alive? }
if code_snippets.empty? && active_threads.select(&:alive?).any?
# block until we've fetched another code snippet
puts "Blocking on HTML request to return, #{active_threads.length} threads in queue"
blocking_thread = active_threads.pop 0
blocking_thread.join
end
break if active_threads.empty?
# If cascading snippets is off, lets go ahead and stop overriding method_missing so we
# don't repeatedly call it if snippets aren't already valid ruby.
unless CASCADE_SNIPPETS && private_methods.include? :method_missing
method_missing_snapshot = method(:method_missing)
send(:define_method, :method_missing, ->(_){ })
end
# Attempt to run the next code snippet, and if it works, run with it
begin
snippet = code_snippets.pop 0
puts "Evaluating code snippet:\n#{snippet}"
retval = eval snippet
# Restore method_missing if we disabled it earlier
send(:define_method, :method_missing, method_missing_snapshot) unless CASCADE_SNIPPETS
# code is eval'd now, so we can just return its return value from method_missing
# if it didn't throw an exception, as if it ran in the first place!
return retval
rescue
end
end
active_threads.map &:join
end
derp "some_func", "other param"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment