Class: Pal::REPL
- Inherits:
-
Object
- Object
- Pal::REPL
- Defined in:
- lib/pal.rb
Overview
Public: Creates a REPL instance.
Class Attribute Summary collapse
-
.messenger ⇒ Object
readonly
Internal: Gets the current REPL instance.
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Public: Gets the evaluation context associated with the REPL instance.
-
#name ⇒ Object
readonly
Public: Gets the name of the REPL instance, used to generate the prompt text and debugging information.
-
#result ⇒ Object
readonly
Public: Gets the result of the last-evaluated expression.
Class Method Summary collapse
-
.create(name = "pal", context = Context.new) ⇒ Object
Public: Creates a new REPL instance.
Instance Method Summary collapse
-
#evaluate(value) ⇒ Object
Public: Evaluates a line of code in the current context.
-
#initialize(name, context) ⇒ REPL
constructor
A new instance of REPL.
-
#loop ⇒ Object
Public: Starts the REPL.
-
#print(result) ⇒ Object
Public: Prints the last output, prepending the output symbol to a human-readable representation of the result.
-
#read(prompt = @name) ⇒ Object
Public: Reads, evaluates, and prints a line of Ruby code.
Constructor Details
#initialize(name, context) ⇒ REPL
Returns a new instance of REPL.
44 45 46 47 48 49 |
# File 'lib/pal.rb', line 44 def initialize(name, context) @name = name @context = context @line = 1 @statements = [] end |
Class Attribute Details
.messenger ⇒ Object (readonly)
Internal: Gets the current REPL instance.
34 35 36 |
# File 'lib/pal.rb', line 34 def messenger @messenger end |
Instance Attribute Details
#context ⇒ Object (readonly)
Public: Gets the evaluation context associated with the REPL instance.
27 28 29 |
# File 'lib/pal.rb', line 27 def context @context end |
#name ⇒ Object (readonly)
Public: Gets the name of the REPL instance, used to generate the prompt text and debugging information.
24 25 26 |
# File 'lib/pal.rb', line 24 def name @name end |
#result ⇒ Object (readonly)
Public: Gets the result of the last-evaluated expression.
30 31 32 |
# File 'lib/pal.rb', line 30 def result @result end |
Class Method Details
.create(name = "pal", context = Context.new) ⇒ Object
Public: Creates a new REPL instance. The ‘messenger` class instance variable is used by the REPL instance to correctly set and expose the result of the last-evaluated expression to the evaluation context.
39 40 41 |
# File 'lib/pal.rb', line 39 def create(name = "pal", context = Context.new) @messenger = new(name, context) end |
Instance Method Details
#evaluate(value) ⇒ Object
Public: Evaluates a line of code in the current context. If an error was raised, the stack trace is printed. To reduce noise, all lines containing the current file name are removed.
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/pal.rb', line 87 def evaluate(value) @result = eval(value, @context.instance_eval { binding }, "(#{@name})", @line) @context.instance_variable_set(:@_, REPL.messenger.result) rescue Exception => exception @error = true stack = exception.backtrace.take_while { |line| not line.include? File.basename(__FILE__) } stack.unshift exception. warn %Q{#{exception.class}: #{stack.join($/ + " " * 4)}} ensure @line += 1 end |
#loop ⇒ Object
Public: Starts the REPL. The REPL will persist until an ‘exit` signal is received.
53 54 55 56 57 |
# File 'lib/pal.rb', line 53 def loop catch :exit do read while true end end |
#print(result) ⇒ Object
Public: Prints the last output, prepending the output symbol to a human-readable representation of the result.
101 102 103 |
# File 'lib/pal.rb', line 101 def print(result) puts "=> #{result.inspect}" unless @error end |
#read(prompt = @name) ⇒ Object
Public: Reads, evaluates, and prints a line of Ruby code. If the line is ‘exit` or `quit`, an `exit` signal is sent and the loop terminates. If an interrupt is sent via Control-C, a blank line is printed before exiting. Multiple lines of code may be evaluated by terminating each line with an escape character (``).
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/pal.rb', line 64 def read(prompt = @name) @error = nil @input = Readline.readline("#{prompt}> ", true) throw :exit if @input.nil? || %w{exit quit}.include?(@input) unless @input.empty? @statements << @input if @statements.last[-1] == "\\" @statements.last.chop! read ?. * @name.size else @input = @statements.join($/) @statements.clear evaluate @input print @result end end rescue Interrupt puts end |