Created
March 23, 2010 03:07
-
-
Save postmodern/340811 to your computer and use it in GitHub Desktop.
An asynchronous Console that can evaluate Ruby code in the background.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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