Skip to content

Instantly share code, notes, and snippets.

@tdegrunt
Forked from postmodern/async_console.rb
Created February 5, 2018 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tdegrunt/1d839f34210f780e547648dc2a07ee43 to your computer and use it in GitHub Desktop.
Save tdegrunt/1d839f34210f780e547648dc2a07ee43 to your computer and use it in GitHub Desktop.
An asynchronous Console that can evaluate Ruby code in the background.
require 'thread'
class AsyncConsole
#
# Creates a new Asynchronous Console, within the given context.
#
# @param [Module] context
# The context to evaluate code within.
#
def initialize(context=Kernel)
@line = 0
@input = Queue.new
@output = Queue.new
@thread = Thread.new(context) do |context|
sandbox = Object.new
sandbox.extend context
scope = sandbox.send :binding
loop do
line, code = @input.pop
begin
result = if code.kind_of?(Proc)
sandbox.instance_eval(&code)
else
eval(code,scope)
end
message = [line, :result, result]
rescue Exception => e
message = [line, :exception, e]
end
@output.push message
end
end
end
#
# Enqueues Ruby code or a block to be evaluated.
#
# @param [String] code
# The Ruby code to evaluate.
#
# @yield []
# If a block is given, it will be evaluated.
#
# @return [AsyncConsole]
# The Asynchronous Console.
#
def push(code=nil,&block)
@input.push [@line += 1, (code || block)]
return self
end
#
# Determines whether the output queue is empty.
#
# @return [Boolean]
# The state of the output queue.
#
def empty?
@output.empy?
end
#
# Dequeues a result.
#
# @return [Array]
# The result Array.
#
def pull
@output.pop unless @output.empty?
end
#
# Enumerates over the results in the output queue.
#
# @yield [result]
# The given block will be passed each result.
#
# @yieldparam [Array] result
# A result from a previous evaluation.
#
def each(&block)
until @output.empty?
block.call(@output.pop)
end
return self
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment