rubysl-irb 1.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/lib/irb/cmd/chws.rb +6 -6
- data/lib/irb/cmd/fork.rb +10 -10
- data/lib/irb/cmd/help.rb +24 -14
- data/lib/irb/cmd/load.rb +8 -7
- data/lib/irb/cmd/nop.rb +8 -8
- data/lib/irb/cmd/pushws.rb +6 -5
- data/lib/irb/cmd/subirb.rb +6 -7
- data/lib/irb/completion.rb +90 -58
- data/lib/irb/context.rb +197 -30
- data/lib/irb/ext/change-ws.rb +17 -10
- data/lib/irb/ext/history.rb +20 -10
- data/lib/irb/ext/loader.rb +22 -12
- data/lib/irb/ext/math-mode.rb +16 -6
- data/lib/irb/ext/multi-irb.rb +69 -24
- data/lib/irb/ext/save-history.rb +87 -37
- data/lib/irb/ext/tracer.rb +17 -7
- data/lib/irb/ext/use-loader.rb +14 -6
- data/lib/irb/ext/workspaces.rb +16 -6
- data/lib/irb/extend-command.rb +92 -34
- data/lib/irb/frame.rb +18 -5
- data/lib/irb/help.rb +20 -19
- data/lib/irb/init.rb +156 -104
- data/lib/irb/input-method.rb +96 -23
- data/lib/irb/inspector.rb +145 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +8 -7
- data/lib/irb/lc/{help-message.rb → help-message} +14 -11
- data/lib/irb/lc/ja/encoding_aliases.rb +10 -0
- data/lib/irb/lc/ja/error.rb +19 -16
- data/lib/irb/lc/ja/help-message +33 -28
- data/lib/irb/locale.rb +83 -85
- data/lib/irb/magic-file.rb +37 -0
- data/lib/irb/notifier.rb +101 -15
- data/lib/irb/output-method.rb +38 -32
- data/lib/irb/ruby-lex.rb +143 -81
- data/lib/irb/ruby-token.rb +13 -19
- data/lib/irb/slex.rb +26 -27
- data/lib/irb/src_encoding.rb +4 -0
- data/lib/irb/version.rb +6 -7
- data/lib/irb/workspace.rb +22 -15
- data/lib/irb/ws-for-case-2.rb +5 -6
- data/lib/irb/xmp.rb +91 -4
- data/lib/rubysl/irb/irb.rb +523 -175
- data/lib/rubysl/irb/version.rb +1 -1
- data/rubysl-irb.gemspec +7 -6
- metadata +35 -15
data/lib/rubysl/irb/irb.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
#
|
2
2
|
# irb.rb - irb main module
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
3
|
+
# $Release Version: 0.9.6 $
|
4
|
+
# $Revision$
|
5
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
6
|
#
|
8
7
|
# --
|
9
8
|
#
|
@@ -22,19 +21,341 @@ require "irb/locale"
|
|
22
21
|
|
23
22
|
STDOUT.sync = true
|
24
23
|
|
24
|
+
# IRB stands for "interactive ruby" and is a tool to interactively execute ruby
|
25
|
+
# expressions read from the standard input.
|
26
|
+
#
|
27
|
+
# The +irb+ command from your shell will start the interpreter.
|
28
|
+
#
|
29
|
+
# == Usage
|
30
|
+
#
|
31
|
+
# Use of irb is easy if you know ruby.
|
32
|
+
#
|
33
|
+
# When executing irb, prompts are displayed as follows. Then, enter the ruby
|
34
|
+
# expression. An input is executed when it is syntactically complete.
|
35
|
+
#
|
36
|
+
# $ irb
|
37
|
+
# irb(main):001:0> 1+2
|
38
|
+
# #=> 3
|
39
|
+
# irb(main):002:0> class Foo
|
40
|
+
# irb(main):003:1> def foo
|
41
|
+
# irb(main):004:2> print 1
|
42
|
+
# irb(main):005:2> end
|
43
|
+
# irb(main):006:1> end
|
44
|
+
# #=> nil
|
45
|
+
#
|
46
|
+
# The Readline extension module can be used with irb. Use of Readline is
|
47
|
+
# default if it's installed.
|
48
|
+
#
|
49
|
+
# == Command line options
|
50
|
+
#
|
51
|
+
# Usage: irb.rb [options] [programfile] [arguments]
|
52
|
+
# -f Suppress read of ~/.irbrc
|
53
|
+
# -m Bc mode (load mathn, fraction or matrix are available)
|
54
|
+
# -d Set $DEBUG to true (same as `ruby -d')
|
55
|
+
# -r load-module Same as `ruby -r'
|
56
|
+
# -I path Specify $LOAD_PATH directory
|
57
|
+
# -U Same as `ruby -U`
|
58
|
+
# -E enc Same as `ruby -E`
|
59
|
+
# -w Same as `ruby -w`
|
60
|
+
# -W[level=2] Same as `ruby -W`
|
61
|
+
# --inspect Use `inspect' for output (default except for bc mode)
|
62
|
+
# --noinspect Don't use inspect for output
|
63
|
+
# --readline Use Readline extension module
|
64
|
+
# --noreadline Don't use Readline extension module
|
65
|
+
# --prompt prompt-mode
|
66
|
+
# --prompt-mode prompt-mode
|
67
|
+
# Switch prompt mode. Pre-defined prompt modes are
|
68
|
+
# `default', `simple', `xmp' and `inf-ruby'
|
69
|
+
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
70
|
+
# Suppresses --readline.
|
71
|
+
# --simple-prompt Simple prompt mode
|
72
|
+
# --noprompt No prompt mode
|
73
|
+
# --tracer Display trace for each execution of commands.
|
74
|
+
# --back-trace-limit n
|
75
|
+
# Display backtrace top n and tail n. The default
|
76
|
+
# value is 16.
|
77
|
+
# --irb_debug n Set internal debug level to n (not for popular use)
|
78
|
+
# -v, --version Print the version of irb
|
79
|
+
#
|
80
|
+
# == Configuration
|
81
|
+
#
|
82
|
+
# IRB reads from <code>~/.irbrc</code> when it's invoked.
|
83
|
+
#
|
84
|
+
# If <code>~/.irbrc</code> doesn't exist, +irb+ will try to read in the following order:
|
85
|
+
#
|
86
|
+
# * +.irbrc+
|
87
|
+
# * +irb.rc+
|
88
|
+
# * +_irbrc+
|
89
|
+
# * <code>$irbrc</code>
|
90
|
+
#
|
91
|
+
# The following are alternatives to the command line options. To use them type
|
92
|
+
# as follows in an +irb+ session:
|
93
|
+
#
|
94
|
+
# IRB.conf[:IRB_NAME]="irb"
|
95
|
+
# IRB.conf[:MATH_MODE]=false
|
96
|
+
# IRB.conf[:INSPECT_MODE]=nil
|
97
|
+
# IRB.conf[:IRB_RC] = nil
|
98
|
+
# IRB.conf[:BACK_TRACE_LIMIT]=16
|
99
|
+
# IRB.conf[:USE_LOADER] = false
|
100
|
+
# IRB.conf[:USE_READLINE] = nil
|
101
|
+
# IRB.conf[:USE_TRACER] = false
|
102
|
+
# IRB.conf[:IGNORE_SIGINT] = true
|
103
|
+
# IRB.conf[:IGNORE_EOF] = false
|
104
|
+
# IRB.conf[:PROMPT_MODE] = :DEFALUT
|
105
|
+
# IRB.conf[:PROMPT] = {...}
|
106
|
+
# IRB.conf[:DEBUG_LEVEL]=0
|
107
|
+
#
|
108
|
+
# === Auto indentation
|
109
|
+
#
|
110
|
+
# To enable auto-indent mode in irb, add the following to your +.irbrc+:
|
111
|
+
#
|
112
|
+
# IRB.conf[:AUTO_INDENT] = true
|
113
|
+
#
|
114
|
+
# === Autocompletion
|
115
|
+
#
|
116
|
+
# To enable autocompletion for irb, add the following to your +.irbrc+:
|
117
|
+
#
|
118
|
+
# require 'irb/completion'
|
119
|
+
#
|
120
|
+
# === History
|
121
|
+
#
|
122
|
+
# By default, irb disables history and will not store any commands you used.
|
123
|
+
#
|
124
|
+
# If you want to enable history, add the following to your +.irbrc+:
|
125
|
+
#
|
126
|
+
# IRB.conf[:SAVE_HISTORY] = 1000
|
127
|
+
#
|
128
|
+
# This will now store the last 1000 commands in <code>~/.irb_history</code>.
|
129
|
+
#
|
130
|
+
# See IRB::Context#save_history= for more information.
|
131
|
+
#
|
132
|
+
# == Customizing the IRB Prompt
|
133
|
+
#
|
134
|
+
# In order to customize the prompt, you can change the following Hash:
|
135
|
+
#
|
136
|
+
# IRB.conf[:PROMPT]
|
137
|
+
#
|
138
|
+
# This example can be used in your +.irbrc+
|
139
|
+
#
|
140
|
+
# IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
|
141
|
+
# :AUTO_INDENT => true # enables auto-indent mode
|
142
|
+
# :PROMPT_I => nil, # normal prompt
|
143
|
+
# :PROMPT_S => nil, # prompt for continuated strings
|
144
|
+
# :PROMPT_C => nil, # prompt for continuated statement
|
145
|
+
# :RETURN => " ==>%s\n" # format to return value
|
146
|
+
# }
|
147
|
+
#
|
148
|
+
# IRB.conf[:PROMPT_MODE] = :MY_PROMPT
|
149
|
+
#
|
150
|
+
# Or, invoke irb with the above prompt mode by:
|
151
|
+
#
|
152
|
+
# irb --prompt my-prompt
|
153
|
+
#
|
154
|
+
# Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
|
155
|
+
# prompt specification, some special strings are available:
|
156
|
+
#
|
157
|
+
# %N # command name which is running
|
158
|
+
# %m # to_s of main object (self)
|
159
|
+
# %M # inspect of main object (self)
|
160
|
+
# %l # type of string(", ', /, ]), `]' is inner %w[...]
|
161
|
+
# %NNi # indent level. NN is degits and means as same as printf("%NNd").
|
162
|
+
# # It can be ommited
|
163
|
+
# %NNn # line number.
|
164
|
+
# %% # %
|
165
|
+
#
|
166
|
+
# For instance, the default prompt mode is defined as follows:
|
167
|
+
#
|
168
|
+
# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
|
169
|
+
# :PROMPT_I => "%N(%m):%03n:%i> ",
|
170
|
+
# :PROMPT_S => "%N(%m):%03n:%i%l ",
|
171
|
+
# :PROMPT_C => "%N(%m):%03n:%i* ",
|
172
|
+
# :RETURN => "%s\n" # used to printf
|
173
|
+
# }
|
174
|
+
#
|
175
|
+
# irb comes with a number of available modes:
|
176
|
+
#
|
177
|
+
# # :NULL:
|
178
|
+
# # :PROMPT_I:
|
179
|
+
# # :PROMPT_N:
|
180
|
+
# # :PROMPT_S:
|
181
|
+
# # :PROMPT_C:
|
182
|
+
# # :RETURN: |
|
183
|
+
# # %s
|
184
|
+
# # :DEFAULT:
|
185
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
186
|
+
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
187
|
+
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
188
|
+
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
189
|
+
# # :RETURN: |
|
190
|
+
# # => %s
|
191
|
+
# # :CLASSIC:
|
192
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
193
|
+
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
194
|
+
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
195
|
+
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
196
|
+
# # :RETURN: |
|
197
|
+
# # %s
|
198
|
+
# # :SIMPLE:
|
199
|
+
# # :PROMPT_I: ! '>> '
|
200
|
+
# # :PROMPT_N: ! '>> '
|
201
|
+
# # :PROMPT_S:
|
202
|
+
# # :PROMPT_C: ! '?> '
|
203
|
+
# # :RETURN: |
|
204
|
+
# # => %s
|
205
|
+
# # :INF_RUBY:
|
206
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
207
|
+
# # :PROMPT_N:
|
208
|
+
# # :PROMPT_S:
|
209
|
+
# # :PROMPT_C:
|
210
|
+
# # :RETURN: |
|
211
|
+
# # %s
|
212
|
+
# # :AUTO_INDENT: true
|
213
|
+
# # :XMP:
|
214
|
+
# # :PROMPT_I:
|
215
|
+
# # :PROMPT_N:
|
216
|
+
# # :PROMPT_S:
|
217
|
+
# # :PROMPT_C:
|
218
|
+
# # :RETURN: |2
|
219
|
+
# # ==>%s
|
220
|
+
#
|
221
|
+
# == Restrictions
|
222
|
+
#
|
223
|
+
# Because irb evaluates input immediately after it is syntactically complete,
|
224
|
+
# the results may be slightly different than directly using ruby.
|
225
|
+
#
|
226
|
+
# == IRB Sessions
|
227
|
+
#
|
228
|
+
# IRB has a special feature, that allows you to manage many sessions at once.
|
229
|
+
#
|
230
|
+
# You can create new sessions with Irb.irb, and get a list of current sessions
|
231
|
+
# with the +jobs+ command in the prompt.
|
232
|
+
#
|
233
|
+
# === Commands
|
234
|
+
#
|
235
|
+
# JobManager provides commands to handle the current sessions:
|
236
|
+
#
|
237
|
+
# jobs # List of current sessions
|
238
|
+
# fg # Switches to the session of the given number
|
239
|
+
# kill # Kills the session with the given number
|
240
|
+
#
|
241
|
+
# The +exit+ command, or ::irb_exit, will quit the current session and call any
|
242
|
+
# exit hooks with IRB.irb_at_exit.
|
243
|
+
#
|
244
|
+
# A few commands for loading files within the session are also available:
|
245
|
+
#
|
246
|
+
# +source+::
|
247
|
+
# Loads a given file in the current session and displays the source lines,
|
248
|
+
# see IrbLoader#source_file
|
249
|
+
# +irb_load+::
|
250
|
+
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
|
251
|
+
# +irb_require+::
|
252
|
+
# Loads the given file similarly to Kernel#require
|
253
|
+
#
|
254
|
+
# === Configuration
|
255
|
+
#
|
256
|
+
# The command line options, or IRB.conf, specify the default behavior of
|
257
|
+
# Irb.irb.
|
258
|
+
#
|
259
|
+
# On the other hand, each conf in IRB@Command+line+options is used to
|
260
|
+
# individually configure IRB.irb.
|
261
|
+
#
|
262
|
+
# If a proc is set for IRB.conf[:IRB_RC], its will be invoked after execution
|
263
|
+
# of that proc with the context of the current session as its argument. Each
|
264
|
+
# session can be configured using this mechanism.
|
265
|
+
#
|
266
|
+
# === Session variables
|
267
|
+
#
|
268
|
+
# There are a few variables in every Irb session that can come in handy:
|
269
|
+
#
|
270
|
+
# <code>_</code>::
|
271
|
+
# The value command executed, as a local variable
|
272
|
+
# <code>__</code>::
|
273
|
+
# The history of evaluated commands
|
274
|
+
# <code>__[line_no]</code>::
|
275
|
+
# Returns the evaluation value at the given line number, +line_no+.
|
276
|
+
# If +line_no+ is a negative, the return value +line_no+ many lines before
|
277
|
+
# the most recent return value.
|
278
|
+
#
|
279
|
+
# === Example using IRB Sessions
|
280
|
+
#
|
281
|
+
# # invoke a new session
|
282
|
+
# irb(main):001:0> irb
|
283
|
+
# # list open sessions
|
284
|
+
# irb.1(main):001:0> jobs
|
285
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
|
286
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : running)
|
287
|
+
#
|
288
|
+
# # change the active session
|
289
|
+
# irb.1(main):002:0> fg 0
|
290
|
+
# # define class Foo in top-level session
|
291
|
+
# irb(main):002:0> class Foo;end
|
292
|
+
# # invoke a new session with the context of Foo
|
293
|
+
# irb(main):003:0> irb Foo
|
294
|
+
# # define Foo#foo
|
295
|
+
# irb.2(Foo):001:0> def foo
|
296
|
+
# irb.2(Foo):002:1> print 1
|
297
|
+
# irb.2(Foo):003:1> end
|
298
|
+
#
|
299
|
+
# # change the active session
|
300
|
+
# irb.2(Foo):004:0> fg 0
|
301
|
+
# # list open sessions
|
302
|
+
# irb(main):004:0> jobs
|
303
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
304
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
305
|
+
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
306
|
+
# # check if Foo#foo is available
|
307
|
+
# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
|
308
|
+
#
|
309
|
+
# # change the active sesssion
|
310
|
+
# irb(main):006:0> fg 2
|
311
|
+
# # define Foo#bar in the context of Foo
|
312
|
+
# irb.2(Foo):005:0> def bar
|
313
|
+
# irb.2(Foo):006:1> print "bar"
|
314
|
+
# irb.2(Foo):007:1> end
|
315
|
+
# irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
|
316
|
+
#
|
317
|
+
# # change the active session
|
318
|
+
# irb.2(Foo):011:0> fg 0
|
319
|
+
# irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
|
320
|
+
# # invoke a new session with the context of f (instance of Foo)
|
321
|
+
# irb(main):008:0> irb f
|
322
|
+
# # list open sessions
|
323
|
+
# irb.3(<Foo:0x4010af3c>):001:0> jobs
|
324
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
|
325
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
326
|
+
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
327
|
+
# #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
|
328
|
+
# # evaluate f.foo
|
329
|
+
# irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
|
330
|
+
# # evaluate f.bar
|
331
|
+
# irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
|
332
|
+
# # kill jobs 1, 2, and 3
|
333
|
+
# irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
|
334
|
+
# # list open sesssions, should only include main session
|
335
|
+
# irb(main):009:0> jobs
|
336
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
337
|
+
# # quit irb
|
338
|
+
# irb(main):010:0> exit
|
25
339
|
module IRB
|
26
|
-
@RCS_ID='-$Id
|
340
|
+
@RCS_ID='-$Id$-'
|
27
341
|
|
342
|
+
# An exception raised by IRB.irb_abort
|
28
343
|
class Abort < Exception;end
|
29
344
|
|
30
|
-
#
|
31
345
|
@CONF = {}
|
32
346
|
|
347
|
+
|
348
|
+
# Displays current configuration.
|
349
|
+
#
|
350
|
+
# Modifing the configuration is achieved by sending a message to IRB.conf.
|
351
|
+
#
|
352
|
+
# See IRB@Configuration for more information.
|
33
353
|
def IRB.conf
|
34
354
|
@CONF
|
35
355
|
end
|
36
356
|
|
37
|
-
# IRB version
|
357
|
+
# Returns the current version of IRB, including release version and last
|
358
|
+
# updated date.
|
38
359
|
def IRB.version
|
39
360
|
if v = @CONF[:VERSION] then return v end
|
40
361
|
|
@@ -43,26 +364,25 @@ module IRB
|
|
43
364
|
@CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
|
44
365
|
end
|
45
366
|
|
367
|
+
# The current IRB::Context of the session, see IRB.conf
|
368
|
+
#
|
369
|
+
# irb
|
370
|
+
# irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
|
371
|
+
# foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
|
46
372
|
def IRB.CurrentContext
|
47
373
|
IRB.conf[:MAIN_CONTEXT]
|
48
374
|
end
|
49
375
|
|
50
|
-
#
|
376
|
+
# Initializes IRB and creates a new Irb.irb object at the +TOPLEVEL_BINDING+
|
51
377
|
def IRB.start(ap_path = nil)
|
52
378
|
$0 = File::basename(ap_path, ".rb") if ap_path
|
53
379
|
|
54
380
|
IRB.setup(ap_path)
|
55
381
|
|
56
|
-
if @CONF[:IRB_CLASS]
|
57
|
-
klass = @CONF[:IRB_CLASS]
|
58
|
-
else
|
59
|
-
klass = Irb
|
60
|
-
end
|
61
|
-
|
62
382
|
if @CONF[:SCRIPT]
|
63
|
-
irb =
|
383
|
+
irb = Irb.new(nil, @CONF[:SCRIPT])
|
64
384
|
else
|
65
|
-
irb =
|
385
|
+
irb = Irb.new
|
66
386
|
end
|
67
387
|
|
68
388
|
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
@@ -71,29 +391,40 @@ module IRB
|
|
71
391
|
trap("SIGINT") do
|
72
392
|
irb.signal_handle
|
73
393
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
394
|
+
|
395
|
+
begin
|
396
|
+
catch(:IRB_EXIT) do
|
397
|
+
irb.eval_input
|
398
|
+
end
|
399
|
+
ensure
|
400
|
+
irb_at_exit
|
77
401
|
end
|
78
402
|
# print "\n"
|
79
403
|
end
|
80
404
|
|
405
|
+
# Calls each event hook of IRB.conf[:AT_EXIT] when the current session quits.
|
406
|
+
def IRB.irb_at_exit
|
407
|
+
@CONF[:AT_EXIT].each{|hook| hook.call}
|
408
|
+
end
|
409
|
+
|
410
|
+
# Quits irb
|
81
411
|
def IRB.irb_exit(irb, ret)
|
82
412
|
throw :IRB_EXIT, ret
|
83
413
|
end
|
84
414
|
|
415
|
+
# Aborts then interrupts irb.
|
416
|
+
#
|
417
|
+
# Will raise an Abort exception, or the given +exception+.
|
85
418
|
def IRB.irb_abort(irb, exception = Abort)
|
86
419
|
if defined? Thread
|
87
|
-
irb.context.thread.raise exception, "abort then interrupt
|
420
|
+
irb.context.thread.raise exception, "abort then interrupt!"
|
88
421
|
else
|
89
|
-
raise exception, "abort then interrupt
|
422
|
+
raise exception, "abort then interrupt!"
|
90
423
|
end
|
91
424
|
end
|
92
425
|
|
93
|
-
#
|
94
|
-
# irb interpriter main routine
|
95
|
-
#
|
96
426
|
class Irb
|
427
|
+
# Creates a new irb session
|
97
428
|
def initialize(workspace = nil, input_method = nil, output_method = nil)
|
98
429
|
@context = Context.new(self, workspace, input_method, output_method)
|
99
430
|
@context.main.extend ExtendCommandBundle
|
@@ -102,236 +433,253 @@ module IRB
|
|
102
433
|
@scanner = RubyLex.new
|
103
434
|
@scanner.exception_on_syntax_error = false
|
104
435
|
end
|
436
|
+
# Returns the current context of this irb session
|
105
437
|
attr_reader :context
|
438
|
+
# The lexer used by this irb session
|
106
439
|
attr_accessor :scanner
|
107
440
|
|
441
|
+
# Evaluates input for this session.
|
108
442
|
def eval_input
|
109
443
|
@scanner.set_prompt do
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
444
|
+
|ltype, indent, continue, line_no|
|
445
|
+
if ltype
|
446
|
+
f = @context.prompt_s
|
447
|
+
elsif continue
|
448
|
+
f = @context.prompt_c
|
449
|
+
elsif indent > 0
|
450
|
+
f = @context.prompt_n
|
451
|
+
else
|
452
|
+
f = @context.prompt_i
|
453
|
+
end
|
454
|
+
f = "" unless f
|
455
|
+
if @context.prompting?
|
456
|
+
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
457
|
+
else
|
458
|
+
@context.io.prompt = p = ""
|
459
|
+
end
|
460
|
+
if @context.auto_indent_mode
|
461
|
+
unless ltype
|
128
462
|
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
463
|
+
indent * 2 - p.size
|
464
|
+
ind += 2 if continue
|
465
|
+
@context.io.prompt = p + " " * ind if ind > 0
|
466
|
+
end
|
467
|
+
end
|
134
468
|
end
|
135
|
-
|
469
|
+
|
136
470
|
@scanner.set_input(@context.io) do
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
471
|
+
signal_status(:IN_INPUT) do
|
472
|
+
if l = @context.io.gets
|
473
|
+
print l if @context.verbose?
|
474
|
+
else
|
475
|
+
if @context.ignore_eof? and @context.io.readable_after_eof?
|
476
|
+
l = "\n"
|
477
|
+
if @context.verbose?
|
478
|
+
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
479
|
+
end
|
480
|
+
else
|
481
|
+
print "\n"
|
482
|
+
end
|
483
|
+
end
|
484
|
+
l
|
485
|
+
end
|
150
486
|
end
|
151
487
|
|
152
|
-
process_statements
|
153
|
-
end
|
154
|
-
|
155
|
-
def process_statements
|
156
488
|
@scanner.each_top_level_statement do |line, line_no|
|
157
|
-
|
158
|
-
|
489
|
+
signal_status(:IN_EVAL) do
|
490
|
+
begin
|
159
491
|
line.untaint
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
492
|
+
@context.evaluate(line, line_no)
|
493
|
+
output_value if @context.echo?
|
494
|
+
exc = nil
|
495
|
+
rescue Interrupt => exc
|
496
|
+
rescue SystemExit, SignalException
|
497
|
+
raise
|
498
|
+
rescue Exception => exc
|
499
|
+
end
|
500
|
+
if exc
|
501
|
+
print exc.class, ": ", exc, "\n"
|
502
|
+
if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
503
|
+
!(SyntaxError === exc)
|
504
|
+
irb_bug = true
|
505
|
+
else
|
506
|
+
irb_bug = false
|
507
|
+
end
|
508
|
+
|
509
|
+
messages = []
|
510
|
+
lasts = []
|
511
|
+
levels = 0
|
512
|
+
for m in exc.backtrace
|
513
|
+
m = @context.workspace.filter_backtrace(m) unless irb_bug
|
514
|
+
if m
|
515
|
+
if messages.size < @context.back_trace_limit
|
516
|
+
messages.push "\tfrom "+m
|
517
|
+
else
|
518
|
+
lasts.push "\tfrom "+m
|
519
|
+
if lasts.size > @context.back_trace_limit
|
520
|
+
lasts.shift
|
521
|
+
levels += 1
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
end
|
526
|
+
print messages.join("\n"), "\n"
|
527
|
+
unless lasts.empty?
|
528
|
+
printf "... %d levels...\n", levels if levels > 0
|
529
|
+
print lasts.join("\n")
|
530
|
+
end
|
531
|
+
print "Maybe IRB bug!\n" if irb_bug
|
532
|
+
end
|
200
533
|
if $SAFE > 2
|
201
534
|
abort "Error: irb does not work for $SAFE level higher than 2"
|
202
535
|
end
|
203
|
-
|
536
|
+
end
|
204
537
|
end
|
205
538
|
end
|
206
539
|
|
540
|
+
# Evaluates the given block using the given +path+ as the Context#irb_path
|
541
|
+
# and +name+ as the Context#irb_name.
|
542
|
+
#
|
543
|
+
# Used by the irb command +source+, see IRB@IRB+Sessions for more
|
544
|
+
# information.
|
207
545
|
def suspend_name(path = nil, name = nil)
|
208
546
|
@context.irb_path, back_path = path, @context.irb_path if path
|
209
547
|
@context.irb_name, back_name = name, @context.irb_name if name
|
210
548
|
begin
|
211
|
-
|
549
|
+
yield back_path, back_name
|
212
550
|
ensure
|
213
|
-
|
214
|
-
|
551
|
+
@context.irb_path = back_path if path
|
552
|
+
@context.irb_name = back_name if name
|
215
553
|
end
|
216
554
|
end
|
217
555
|
|
556
|
+
# Evaluates the given block using the given +workspace+ as the
|
557
|
+
# Context#workspace.
|
558
|
+
#
|
559
|
+
# Used by the irb command +irb_load+, see IRB@IRB+Sessions for more
|
560
|
+
# information.
|
218
561
|
def suspend_workspace(workspace)
|
219
562
|
@context.workspace, back_workspace = workspace, @context.workspace
|
220
563
|
begin
|
221
|
-
|
564
|
+
yield back_workspace
|
222
565
|
ensure
|
223
|
-
|
566
|
+
@context.workspace = back_workspace
|
224
567
|
end
|
225
568
|
end
|
226
569
|
|
570
|
+
# Evaluates the given block using the given +input_method+ as the
|
571
|
+
# Context#io.
|
572
|
+
#
|
573
|
+
# Used by the irb commands +source+ and +irb_load+, see IRB@IRB+Sessions
|
574
|
+
# for more information.
|
227
575
|
def suspend_input_method(input_method)
|
228
576
|
back_io = @context.io
|
229
577
|
@context.instance_eval{@io = input_method}
|
230
578
|
begin
|
231
|
-
|
579
|
+
yield back_io
|
232
580
|
ensure
|
233
|
-
|
581
|
+
@context.instance_eval{@io = back_io}
|
234
582
|
end
|
235
583
|
end
|
236
584
|
|
585
|
+
# Evaluates the given block using the given +context+ as the Context.
|
237
586
|
def suspend_context(context)
|
238
587
|
@context, back_context = context, @context
|
239
588
|
begin
|
240
|
-
|
589
|
+
yield back_context
|
241
590
|
ensure
|
242
|
-
|
591
|
+
@context = back_context
|
243
592
|
end
|
244
593
|
end
|
245
594
|
|
595
|
+
# Handler for the signal SIGINT, see Kernel#trap for more information.
|
246
596
|
def signal_handle
|
247
597
|
unless @context.ignore_sigint?
|
248
|
-
|
249
|
-
|
598
|
+
print "\nabort!\n" if @context.verbose?
|
599
|
+
exit
|
250
600
|
end
|
251
601
|
|
252
602
|
case @signal_status
|
253
603
|
when :IN_INPUT
|
254
|
-
|
255
|
-
|
604
|
+
print "^C\n"
|
605
|
+
raise RubyLex::TerminateLineInput
|
256
606
|
when :IN_EVAL
|
257
|
-
|
607
|
+
IRB.irb_abort(self)
|
258
608
|
when :IN_LOAD
|
259
|
-
|
609
|
+
IRB.irb_abort(self, LoadAbort)
|
260
610
|
when :IN_IRB
|
261
|
-
|
611
|
+
# ignore
|
262
612
|
else
|
263
|
-
|
613
|
+
# ignore other cases as well
|
264
614
|
end
|
265
615
|
end
|
266
616
|
|
617
|
+
# Evaluates the given block using the given +status+.
|
267
618
|
def signal_status(status)
|
268
619
|
return yield if @signal_status == :IN_LOAD
|
269
620
|
|
270
621
|
signal_status_back = @signal_status
|
271
622
|
@signal_status = status
|
272
623
|
begin
|
273
|
-
|
624
|
+
yield
|
274
625
|
ensure
|
275
|
-
|
626
|
+
@signal_status = signal_status_back
|
276
627
|
end
|
277
628
|
end
|
278
629
|
|
279
|
-
def prompt(prompt, ltype, indent, line_no)
|
630
|
+
def prompt(prompt, ltype, indent, line_no) # :nodoc:
|
280
631
|
p = prompt.dup
|
281
632
|
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
633
|
+
case $2
|
634
|
+
when "N"
|
635
|
+
@context.irb_name
|
636
|
+
when "m"
|
637
|
+
@context.main.to_s
|
638
|
+
when "M"
|
639
|
+
@context.main.inspect
|
640
|
+
when "l"
|
641
|
+
ltype
|
642
|
+
when "i"
|
643
|
+
if $1
|
644
|
+
format("%" + $1 + "d", indent)
|
645
|
+
else
|
646
|
+
indent.to_s
|
647
|
+
end
|
648
|
+
when "n"
|
649
|
+
if $1
|
650
|
+
format("%" + $1 + "d", line_no)
|
651
|
+
else
|
652
|
+
line_no.to_s
|
653
|
+
end
|
654
|
+
when "%"
|
655
|
+
"%"
|
656
|
+
end
|
306
657
|
end
|
307
658
|
p
|
308
659
|
end
|
309
660
|
|
310
|
-
def output_value
|
311
|
-
|
312
|
-
printf @context.return_format, @context.last_value.inspect
|
313
|
-
else
|
314
|
-
printf @context.return_format, @context.last_value
|
315
|
-
end
|
661
|
+
def output_value # :nodoc:
|
662
|
+
printf @context.return_format, @context.inspect_last_value
|
316
663
|
end
|
317
664
|
|
665
|
+
# Outputs the local variables to this current session, including
|
666
|
+
# #signal_status and #context, using IRB::Locale.
|
318
667
|
def inspect
|
319
668
|
ary = []
|
320
669
|
for iv in instance_variables
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
670
|
+
case (iv = iv.to_s)
|
671
|
+
when "@signal_status"
|
672
|
+
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
673
|
+
when "@context"
|
674
|
+
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
675
|
+
else
|
676
|
+
ary.push format("%s=%s", iv, eval(iv))
|
677
|
+
end
|
329
678
|
end
|
330
679
|
format("#<%s: %s>", self.class, ary.join(", "))
|
331
680
|
end
|
332
681
|
end
|
333
682
|
|
334
|
-
# Singleton method
|
335
683
|
def @CONF.inspect
|
336
684
|
IRB.version unless self[:VERSION]
|
337
685
|
|
@@ -339,16 +687,16 @@ module IRB
|
|
339
687
|
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
340
688
|
case k
|
341
689
|
when :MAIN_CONTEXT, :__TMP__EHV__
|
342
|
-
|
690
|
+
array.push format("CONF[:%s]=...myself...", k.id2name)
|
343
691
|
when :PROMPT
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
692
|
+
s = v.collect{
|
693
|
+
|kk, vv|
|
694
|
+
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
695
|
+
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
696
|
+
}
|
697
|
+
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
350
698
|
else
|
351
|
-
|
699
|
+
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
352
700
|
end
|
353
701
|
end
|
354
702
|
array.join("\n")
|