Class: Pry::REPL

Inherits:
Object show all
Extended by:
Forwardable
Defined in:
lib/pry/repl.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pry, options = {}) ⇒ REPL

Create an instance of Pry::REPL wrapping the given Pry.

Options Hash (options):

  • :target (Object)

    The initial target of the session.



22
23
24
25
26
27
28
29
# File 'lib/pry/repl.rb', line 22

def initialize(pry, options = {})
  @pry    = pry
  @indent = Pry::Indent.new

  if options[:target]
    @pry.push_binding options[:target]
  end
end

Instance Attribute Details

#pryPry



9
10
11
# File 'lib/pry/repl.rb', line 9

def pry
  @pry
end

Class Method Details

.start(options) ⇒ Object

Instantiate a new Pry instance with the given options, then start a Pry::REPL instance wrapping it.

Options Hash (options):



14
15
16
# File 'lib/pry/repl.rb', line 14

def self.start(options)
  new(Pry.new(options)).start
end

Instance Method Details

#epilogue (private)

This method returns an undefined value.

Clean up after the repl session.



84
85
86
# File 'lib/pry/repl.rb', line 84

def epilogue
  pry.exec_hook :after_session, pry.output, pry.current_binding, pry
end

#handle_read_errorsObject, :no_more_input (private)

Manage switching of input objects on encountering EOFErrors.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/pry/repl.rb', line 124

def handle_read_errors
  should_retry = true
  exception_count = 0

  begin
    yield
  rescue EOFError
    pry.config.input = Pry.config.input
    if !should_retry
      output.puts "Error: Pry ran out of things to read from! " \
        "Attempting to break out of REPL."
      return :no_more_input
    end
    should_retry = false
    retry

  # Handle <Ctrl+C> like Bash: empty the current input buffer, but don't
  # quit.  This is only for MRI 1.9; other versions of Ruby don't let you
  # send Interrupt from within Readline.
  rescue Interrupt
    return :control_c

  # If we get a random error when trying to read a line we don't want to
  # automatically retry, as the user will see a lot of error messages
  # scroll past and be unable to do anything about it.
  rescue RescuableException => e
    puts "Error: #{e.message}"
    output.puts e.backtrace
    exception_count += 1
    if exception_count < 5
      retry
    end
    puts "FATAL: Pry failed to get user input using `#{input}`."
    puts "To fix this you may be able to pass input and output file " \
      "descriptors to pry directly. e.g."
    puts "  Pry.config.input = STDIN"
    puts "  Pry.config.output = STDOUT"
    puts "  binding.pry"
    return :no_more_input
  end
end

#input_readline(*args) ⇒ Object (private)



199
200
201
202
203
# File 'lib/pry/repl.rb', line 199

def input_readline(*args)
  Pry::InputLock.for(:all).interruptible_region do
    input.readline(*args)
  end
end

#prologue (private)

This method returns an undefined value.

Set up the repl session.



47
48
49
50
51
52
53
54
# File 'lib/pry/repl.rb', line 47

def prologue
  pry.exec_hook :before_session, pry.output, pry.current_binding, pry

  # Clear the line before starting Pry. This fixes issue #566.
  if pry.config.correct_indent
    Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G"
  end
end

#readString, ... (private)

Read a line of input from the user.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/pry/repl.rb', line 93

def read
  @indent.reset if pry.eval_string.empty?
  current_prompt = pry.select_prompt
  indentation = pry.config.auto_indent ? @indent.current_prefix : ''

  val = read_line("#{current_prompt}#{indentation}")

  # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
  return val unless String === val

  if pry.config.auto_indent
    original_val = "#{indentation}#{val}"
    indented_val = @indent.indent(val)

    if output.tty? && pry.config.correct_indent && Pry::Helpers::BaseHelpers.use_ansi_codes?
      output.print @indent.correct_indentation(
        current_prompt, indented_val,
        original_val.length - indented_val.length
      )
      output.flush
    end
  else
    indented_val = val
  end

  indented_val
end

#read_line(current_prompt) ⇒ String? (private)

Returns the next line of input to be sent to the Pry instance.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/pry/repl.rb', line 169

def read_line(current_prompt)
  handle_read_errors do
    if defined? Coolline and input.is_a? Coolline
      input.completion_proc = proc do |cool|
        completions = @pry.complete cool.completed_word
        completions.compact
      end
    elsif input.respond_to? :completion_proc=
      input.completion_proc = proc do |input|
        @pry.complete input
      end
    end

    if defined?(Readline) and input == Readline
      if !$stdout.tty? && $stdin.tty? && !Pry::Helpers::BaseHelpers.windows?
        Readline.output = File.open('/dev/tty', 'w')
      end
      input_readline(current_prompt, false) # false since we'll add it manually
    elsif defined? Coolline and input.is_a? Coolline
      input_readline(current_prompt)
    else
      if input.method(:readline).arity == 1
        input_readline(current_prompt)
      else
        input_readline
      end
    end
  end
end

#replObject? (private)

The actual read-eval-print loop.

The Pry::REPL instance is responsible for reading and looping, whereas the Pry instance is responsible for evaluating user input and printing return values and command output.

Raises:

  • (Exception)

    If the session throws :raise_up, raise the exception thrown with it.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/pry/repl.rb', line 66

def repl
  loop do
    case val = read
    when :control_c
      output.puts ""
      pry.reset_eval_string
    when :no_more_input
      output.puts "" if output.tty?
      break
    else
      output.puts "" if val.nil? && output.tty?
      return pry.exit_value unless pry.eval(val)
    end
  end
end

#startObject?

Start the read-eval-print loop.

Raises:

  • (Exception)

    If the session throws :raise_up, raise the exception thrown with it.



36
37
38
39
40
41
# File 'lib/pry/repl.rb', line 36

def start
  prologue
  Pry::InputLock.for(:all).with_ownership { repl }
ensure
  epilogue
end