Class: Pal::REPL

Inherits:
Object
  • Object
show all
Defined in:
lib/pal.rb

Overview

Public: Creates a REPL instance.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, context) ⇒ REPL

Returns a new instance of REPL.



30
31
32
33
34
35
# File 'lib/pal.rb', line 30

def initialize(name, context)
  @name = name
  @context = context
  @line = 1
  @statements = []
end

Instance Attribute Details

#contextObject (readonly)

Public: Gets the evaluation context associated with the REPL instance.



25
26
27
# File 'lib/pal.rb', line 25

def context
  @context
end

#nameObject (readonly)

Public: Gets the name of the REPL instance, used to generate the prompt text and debugging information.



22
23
24
# File 'lib/pal.rb', line 22

def name
  @name
end

#resultObject (readonly)

Public: Gets the result of the last-evaluated expression.



28
29
30
# File 'lib/pal.rb', line 28

def result
  @result
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 omitted from the trace.



83
84
85
86
87
88
89
90
91
92
# File 'lib/pal.rb', line 83

def evaluate(value)
  @result = eval(value, @context.instance_eval { binding }, "(#{@name})", @line)
  @context.instance_variable_set(:@_, result)
rescue Exception => exception
  @error = true
  trace = exception.backtrace.reject { |line| line.include? File.basename(__FILE__) }.unshift(exception.message)
  warn "#{exception.class}: #{trace.join("\n\t")}"
ensure
  @line += 1
end

#get(prompt) ⇒ Object

Public: Gets a line from the standard input using Readline.



47
48
49
50
# File 'lib/pal.rb', line 47

def get(prompt)
  require "readline"
  Readline.readline("#{prompt}> ", true)
end

#loopObject

Public: Starts the REPL. The REPL will persist until an ‘exit` signal is received.



39
40
41
42
43
44
# File 'lib/pal.rb', line 39

def loop
  catch :exit do
    read while true
  end
  self
end

Public: Prints the last output, prepending the output symbol to a human-readable representation of the result.



96
97
98
# File 'lib/pal.rb', line 96

def print(result)
  put "=> #{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 (``).



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/pal.rb', line 60

def read(prompt = @name)
  @error = nil
  @input = get prompt
  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