Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 3f5f71bae1
Fetching contributors…

Cannot retrieve contributors at this time

127 lines (106 sloc) 3.581 kb
# MacRuby implementation of IRB.
#
# This file is covered by the Ruby license. See COPYING for more details.
#
# Copyright (C) 2009-2010, Eloy Duran <eloy.de.enige@gmail.com>
require 'irb/formatter'
require 'irb/source'
module IRB
class Context
IGNORE_RESULT = :irb_ignore_result
attr_reader :object, :binding, :line, :level, :source
attr_accessor :formatter
def initialize(object, explicit_binding = nil)
@object = object
@binding = explicit_binding || object.instance_eval { binding }
@line = 1
@level = 0
clear_buffer
@last_result_assigner = __evaluate__("_ = nil; proc { |val| _ = val }")
@exception_assigner = __evaluate__("e = exception = nil; proc { |ex| e = exception = ex }")
end
def __evaluate__(source, file = __FILE__, line = __LINE__)
eval(source, @binding, file, line)
end
def to_s
object_description = "`#{object.inspect}'"
object_description = "of class `#{object.class.name}'" if object_description.length > 32
"#<IRB::Context for object #{object_description}>"
end
alias_method :inspect, :to_s
def evaluate(source)
result = __evaluate__(source.to_s, '(irb)', @line - @source.buffer.size + 1)
unless IGNORE_RESULT == result
store_result(result)
output(formatter.result(result))
result
end
rescue Exception => e
store_exception(e)
output(formatter.exception(e))
end
# Returns whether or not the user wants to continue the current runloop.
# This can only be done at a code block indentation level of 0.
#
# For instance, this will continue:
#
# process_line("def foo") # => true
# process_line("quit") # => true
# process_line("end") # => true
#
# But at code block indentation level 0, `quit' means exit the runloop:
#
# process_line("quit") # => false
#
# If re-indenting the line results in a new line, the reformatted line and
# prompt are yielded to the optional block. This happens *before* the line
# is actually processed, so the caller (driver) has the opportunity to
# update the last printed line.
def process_line(line)
prompt_and_line = formatter.reindent_last_line(self) { @source << line }
yield(*prompt_and_line) if prompt_and_line && block_given?
return false if @source.terminate?
if @source.syntax_error?
output(formatter.syntax_error(@line, @source.syntax_error))
@source.pop
elsif @source.code_block?
evaluate(@source)
clear_buffer
end
@line += 1
@level = source.level
true
end
def driver
IRB::Driver.current
end
# Output is directed to the IRB::Driver.current driver’s output if a
# current driver is available. Otherwise it’s simply printed to $stdout.
def output(string)
if driver = self.driver
driver.output.puts(string)
else
puts(string)
end
end
def prompt(ignore_auto_indent = false)
formatter.prompt(self, ignore_auto_indent)
end
def input_line(line)
output(formatter.prompt(self) + line)
process_line(line)
end
def formatter
@formatter ||= IRB.formatter
end
def clear_buffer
@source = Source.new
end
def store_result(result)
@last_result_assigner.call(result)
end
def store_exception(exception)
@exception_assigner.call(exception)
end
end
end
Jump to Line
Something went wrong with that request. Please try again.