Class: IRB::Irb

Inherits:
Object show all
Defined in:
lib/irb.rb,
lib/irb/ext/multi-irb.rb

Overview

irb interpriter main routine

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workspace = nil, input_method = nil, output_method = nil) ⇒ Irb

Returns a new instance of Irb.



91
92
93
94
95
96
97
98
# File 'lib/irb.rb', line 91

def initialize(workspace = nil, input_method = nil, output_method = nil)
  @context = Context.new(self, workspace, input_method, output_method)
  @context.main.extend ExtendCommandBundle
  @signal_status = :IN_IRB

  @scanner = RubyLex.new
  @scanner.exception_on_syntax_error = false
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context



99
100
101
# File 'lib/irb.rb', line 99

def context
  @context
end

#scannerObject

Returns the value of attribute scanner



100
101
102
# File 'lib/irb.rb', line 100

def scanner
  @scanner
end

Instance Method Details

#eval_inputObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
165
166
167
168
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
# File 'lib/irb.rb', line 102

def eval_input
  @scanner.set_prompt do
	|ltype, indent, continue, line_no|
	if ltype
	  f = @context.prompt_s
	elsif continue
	  f = @context.prompt_c
	elsif indent > 0
	  f = @context.prompt_n
	else @context.prompt_i
	  f = @context.prompt_i
	end
	f = "" unless f
	if @context.prompting?
	  @context.io.prompt = p = prompt(f, ltype, indent, line_no)
	else
	  @context.io.prompt = p = ""
	end
	if @context.auto_indent_mode
	  unless ltype
        ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
   indent * 2 - p.size
 ind += 2 if continue
 @context.io.prompt = p + " " * ind if ind > 0
	  end
	end
  end
   
  @scanner.set_input(@context.io) do
	signal_status(:IN_INPUT) do
	  if l = @context.io.gets
 print l if @context.verbose?
	  else
 if @context.ignore_eof? and @context.io.readable_atfer_eof?
   l = "\n"
   if @context.verbose?
		printf "Use \"exit\" to leave %s\n", @context.ap_name
   end
 end
	  end
	  l
	end
  end

  @scanner.each_top_level_statement do |line, line_no|
	signal_status(:IN_EVAL) do
	  begin
        line.untaint
 @context.evaluate(line, line_no)
 output_value if @context.echo?
 exc = nil
	  rescue Interrupt => exc
	  rescue SystemExit, SignalException
 raise
	  rescue Exception => exc
	  end
	  if exc
 print exc.class, ": ", exc, "\n"
 if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/
   irb_bug = true 
 else
   irb_bug = false
 end
 
 messages = []
 lasts = []
 levels = 0
 for m in exc.backtrace
   m = @context.workspace.filter_backtrace(m) unless irb_bug
   if m
		if messages.size < @context.back_trace_limit
messages.push "\tfrom "+m
		else
lasts.push "\tfrom "+m
if lasts.size > @context.back_trace_limit
  lasts.shift 
  levels += 1
end
		end
   end
 end
 print messages.join("\n"), "\n"
 unless lasts.empty?
   printf "... %d levels...\n", levels if levels > 0
   print lasts.join("\n")
 end
 print "Maybe IRB bug!!\n" if irb_bug
	  end
      if $SAFE > 2
        abort "Error: irb does not work for $SAFE level higher than 2"
      end
	end
  end
end

#inspectObject



308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/irb.rb', line 308

def inspect
  ary = []
  for iv in instance_variables
	case iv
	when "@signal_status"
	  ary.push format("%s=:%s", iv, @signal_status.id2name)
	when "@context"
	  ary.push format("%s=%s", iv, eval(iv).__to_s__)
	else
	  ary.push format("%s=%s", iv, eval(iv))
	end
  end
  format("#<%s: %s>", self.class, ary.join(", "))
end

#output_valueObject



300
301
302
303
304
305
306
# File 'lib/irb.rb', line 300

def output_value
  if @context.inspect?
    printf @context.return_format, @context.last_value.inspect
  else
    printf @context.return_format, @context.last_value
  end
end

#prompt(prompt, ltype, indent, line_no) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/irb.rb', line 269

def prompt(prompt, ltype, indent, line_no)
  p = prompt.dup
  p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
	case $2
	when "N"
	  @context.irb_name
	when "m"
	  @context.main.to_s
	when "M"
	  @context.main.inspect
	when "l"
	  ltype
	when "i"
	  if $1 
 format("%" + $1 + "d", indent)
	  else
 indent.to_s
	  end
	when "n"
	  if $1 
 format("%" + $1 + "d", line_no)
	  else
 line_no.to_s
	  end
	when "%"
	  "%"
	end
  end
  p
end

#signal_handleObject



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/irb.rb', line 236

def signal_handle
  unless @context.ignore_sigint?
	print "\nabort!!\n" if @context.verbose?
	exit
  end

  case @signal_status
  when :IN_INPUT
	print "^C\n"
	IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
  when :IN_EVAL
	IRB.irb_abort(self)
  when :IN_LOAD
	IRB.irb_abort(self, LoadAbort)
  when :IN_IRB
	# ignore
  else
	# ignore other cases as well
  end
end

#signal_status(status) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
# File 'lib/irb.rb', line 257

def signal_status(status)
  return yield if @signal_status == :IN_LOAD

  signal_status_back = @signal_status
  @signal_status = status
  begin
	yield
  ensure
	@signal_status = signal_status_back
  end
end

#suspend_context(context) ⇒ Object



227
228
229
230
231
232
233
234
# File 'lib/irb.rb', line 227

def suspend_context(context)
  @context, back_context = context, @context
  begin
	yield back_context
  ensure
	@context = back_context
  end
end

#suspend_input_method(input_method) ⇒ Object



217
218
219
220
221
222
223
224
225
# File 'lib/irb.rb', line 217

def suspend_input_method(input_method)
  back_io = @context.io
  @context.instance_eval{@io = input_method}
  begin
	yield back_io
  ensure
	@context.instance_eval{@io = back_io}
  end
end

#suspend_name(path = nil, name = nil) ⇒ Object



197
198
199
200
201
202
203
204
205
206
# File 'lib/irb.rb', line 197

def suspend_name(path = nil, name = nil)
  @context.irb_path, back_path = path, @context.irb_path if path
  @context.irb_name, back_name = name, @context.irb_name if name
  begin
	yield back_path, back_name
  ensure
	@context.irb_path = back_path if path
	@context.irb_name = back_name if name
  end
end

#suspend_workspace(workspace) ⇒ Object



208
209
210
211
212
213
214
215
# File 'lib/irb.rb', line 208

def suspend_workspace(workspace)
  @context.workspace, back_workspace = workspace, @context.workspace
  begin
	yield back_workspace
  ensure
	@context.workspace = back_workspace
  end
end