irb 1.7.1 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.document +1 -1
- data/Gemfile +10 -1
- data/README.md +265 -20
- data/Rakefile +13 -10
- data/doc/irb/irb.rd.ja +1 -3
- data/irb.gemspec +2 -1
- data/lib/irb/cmd/nop.rb +3 -52
- data/lib/irb/color.rb +4 -2
- data/lib/irb/command/backtrace.rb +17 -0
- data/lib/irb/command/base.rb +62 -0
- data/lib/irb/command/break.rb +17 -0
- data/lib/irb/command/catch.rb +17 -0
- data/lib/irb/command/chws.rb +40 -0
- data/lib/irb/command/context.rb +16 -0
- data/lib/irb/{cmd → command}/continue.rb +3 -3
- data/lib/irb/command/debug.rb +71 -0
- data/lib/irb/{cmd → command}/delete.rb +3 -3
- data/lib/irb/command/disable_irb.rb +19 -0
- data/lib/irb/command/edit.rb +63 -0
- data/lib/irb/command/exit.rb +18 -0
- data/lib/irb/{cmd → command}/finish.rb +3 -3
- data/lib/irb/command/force_exit.rb +18 -0
- data/lib/irb/command/help.rb +83 -0
- data/lib/irb/command/history.rb +45 -0
- data/lib/irb/command/info.rb +17 -0
- data/lib/irb/command/internal_helpers.rb +27 -0
- data/lib/irb/{cmd → command}/irb_info.rb +7 -7
- data/lib/irb/{cmd → command}/load.rb +23 -8
- data/lib/irb/{cmd → command}/ls.rb +42 -19
- data/lib/irb/{cmd → command}/measure.rb +18 -17
- data/lib/irb/{cmd → command}/next.rb +3 -3
- data/lib/irb/command/pushws.rb +65 -0
- data/lib/irb/command/show_doc.rb +51 -0
- data/lib/irb/command/show_source.rb +74 -0
- data/lib/irb/{cmd → command}/step.rb +3 -3
- data/lib/irb/command/subirb.rb +123 -0
- data/lib/irb/{cmd → command}/whereami.rb +3 -5
- data/lib/irb/command.rb +23 -0
- data/lib/irb/completion.rb +133 -102
- data/lib/irb/context.rb +182 -66
- data/lib/irb/debug/ui.rb +103 -0
- data/lib/irb/{cmd/debug.rb → debug.rb} +53 -59
- data/lib/irb/default_commands.rb +265 -0
- data/lib/irb/easter-egg.rb +16 -6
- data/lib/irb/ext/change-ws.rb +6 -8
- data/lib/irb/ext/{history.rb → eval_history.rb} +7 -7
- data/lib/irb/ext/loader.rb +4 -4
- data/lib/irb/ext/multi-irb.rb +5 -5
- data/lib/irb/ext/tracer.rb +12 -51
- data/lib/irb/ext/use-loader.rb +6 -8
- data/lib/irb/ext/workspaces.rb +10 -34
- data/lib/irb/frame.rb +1 -1
- data/lib/irb/help.rb +3 -3
- data/lib/irb/helper_method/base.rb +16 -0
- data/lib/irb/helper_method/conf.rb +11 -0
- data/lib/irb/helper_method.rb +29 -0
- data/lib/irb/{ext/save-history.rb → history.rb} +20 -58
- data/lib/irb/init.rb +154 -58
- data/lib/irb/input-method.rb +238 -203
- data/lib/irb/inspector.rb +3 -3
- data/lib/irb/lc/error.rb +1 -11
- data/lib/irb/lc/help-message +4 -0
- data/lib/irb/lc/ja/error.rb +1 -11
- data/lib/irb/lc/ja/help-message +13 -0
- data/lib/irb/locale.rb +2 -2
- data/lib/irb/nesting_parser.rb +13 -3
- data/lib/irb/notifier.rb +1 -1
- data/lib/irb/output-method.rb +2 -8
- data/lib/irb/pager.rb +91 -0
- data/lib/irb/ruby-lex.rb +391 -471
- data/lib/irb/ruby_logo.aa +43 -0
- data/lib/irb/source_finder.rb +139 -0
- data/lib/irb/statement.rb +80 -0
- data/lib/irb/version.rb +3 -3
- data/lib/irb/workspace.rb +24 -4
- data/lib/irb/ws-for-case-2.rb +1 -1
- data/lib/irb/xmp.rb +3 -3
- data/lib/irb.rb +1232 -604
- data/man/irb.1 +7 -0
- metadata +60 -32
- data/lib/irb/cmd/backtrace.rb +0 -21
- data/lib/irb/cmd/break.rb +0 -21
- data/lib/irb/cmd/catch.rb +0 -21
- data/lib/irb/cmd/chws.rb +0 -36
- data/lib/irb/cmd/edit.rb +0 -61
- data/lib/irb/cmd/help.rb +0 -23
- data/lib/irb/cmd/info.rb +0 -21
- data/lib/irb/cmd/pushws.rb +0 -45
- data/lib/irb/cmd/show_cmds.rb +0 -39
- data/lib/irb/cmd/show_doc.rb +0 -48
- data/lib/irb/cmd/show_source.rb +0 -113
- data/lib/irb/cmd/subirb.rb +0 -66
- data/lib/irb/extend-command.rb +0 -356
- data/lib/irb/src_encoding.rb +0 -7
data/lib/irb.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
# frozen_string_literal:
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :markup: markdown
|
3
4
|
# irb.rb - irb main module
|
4
5
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
5
6
|
#
|
@@ -9,399 +10,886 @@ require "reline"
|
|
9
10
|
|
10
11
|
require_relative "irb/init"
|
11
12
|
require_relative "irb/context"
|
12
|
-
require_relative "irb/
|
13
|
+
require_relative "irb/default_commands"
|
13
14
|
|
14
15
|
require_relative "irb/ruby-lex"
|
16
|
+
require_relative "irb/statement"
|
15
17
|
require_relative "irb/input-method"
|
16
18
|
require_relative "irb/locale"
|
17
19
|
require_relative "irb/color"
|
18
20
|
|
19
21
|
require_relative "irb/version"
|
20
22
|
require_relative "irb/easter-egg"
|
23
|
+
require_relative "irb/debug"
|
24
|
+
require_relative "irb/pager"
|
21
25
|
|
22
|
-
# IRB
|
23
|
-
# expressions read from the standard input.
|
26
|
+
# ## IRB
|
24
27
|
#
|
25
|
-
#
|
28
|
+
# Module IRB ("Interactive Ruby") provides a shell-like interface that supports
|
29
|
+
# user interaction with the Ruby interpreter.
|
26
30
|
#
|
27
|
-
#
|
31
|
+
# It operates as a *read-eval-print loop*
|
32
|
+
# ([REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop))
|
33
|
+
# that:
|
28
34
|
#
|
29
|
-
#
|
35
|
+
# * ***Reads*** each character as you type. You can modify the IRB context to
|
36
|
+
# change the way input works. See [Input](rdoc-ref:IRB@Input).
|
37
|
+
# * ***Evaluates*** the code each time it has read a syntactically complete
|
38
|
+
# passage.
|
39
|
+
# * ***Prints*** after evaluating. You can modify the IRB context to change
|
40
|
+
# the way output works. See [Output](rdoc-ref:IRB@Output).
|
30
41
|
#
|
31
|
-
#
|
32
|
-
#
|
42
|
+
#
|
43
|
+
# Example:
|
33
44
|
#
|
34
45
|
# $ irb
|
35
|
-
# irb(main):001
|
36
|
-
#
|
37
|
-
# irb(main):002
|
38
|
-
#
|
39
|
-
# irb(main):
|
40
|
-
# irb(main):
|
41
|
-
# irb(main):
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# The
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
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
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
46
|
+
# irb(main):001> File.basename(Dir.pwd)
|
47
|
+
# => "irb"
|
48
|
+
# irb(main):002> Dir.entries('.').size
|
49
|
+
# => 25
|
50
|
+
# irb(main):003* Dir.entries('.').select do |entry|
|
51
|
+
# irb(main):004* entry.start_with?('R')
|
52
|
+
# irb(main):005> end
|
53
|
+
# => ["README.md", "Rakefile"]
|
54
|
+
#
|
55
|
+
# The typed input may also include [\IRB-specific
|
56
|
+
# commands](rdoc-ref:IRB@IRB-Specific+Commands).
|
57
|
+
#
|
58
|
+
# As seen above, you can start IRB by using the shell command `irb`.
|
59
|
+
#
|
60
|
+
# You can stop an IRB session by typing command `exit`:
|
61
|
+
#
|
62
|
+
# irb(main):006> exit
|
63
|
+
# $
|
64
|
+
#
|
65
|
+
# At that point, IRB calls any hooks found in array `IRB.conf[:AT_EXIT]`, then
|
66
|
+
# exits.
|
67
|
+
#
|
68
|
+
# ## Startup
|
69
|
+
#
|
70
|
+
# At startup, IRB:
|
71
|
+
#
|
72
|
+
# 1. Interprets (as Ruby code) the content of the [configuration
|
73
|
+
# file](rdoc-ref:IRB@Configuration+File) (if given).
|
74
|
+
# 2. Constructs the initial session context from [hash
|
75
|
+
# IRB.conf](rdoc-ref:IRB@Hash+IRB.conf) and from default values; the hash
|
76
|
+
# content may have been affected by [command-line
|
77
|
+
# options](rdoc-ref:IB@Command-Line+Options), and by direct assignments in
|
78
|
+
# the configuration file.
|
79
|
+
# 3. Assigns the context to variable `conf`.
|
80
|
+
# 4. Assigns command-line arguments to variable `ARGV`.
|
81
|
+
# 5. Prints the [prompt](rdoc-ref:IRB@Prompt+and+Return+Formats).
|
82
|
+
# 6. Puts the content of the [initialization
|
83
|
+
# script](rdoc-ref:IRB@Initialization+Script) onto the IRB shell, just as if
|
84
|
+
# it were user-typed commands.
|
85
|
+
#
|
86
|
+
#
|
87
|
+
# ### The Command Line
|
88
|
+
#
|
89
|
+
# On the command line, all options precede all arguments; the first item that is
|
90
|
+
# not recognized as an option is treated as an argument, as are all items that
|
91
|
+
# follow.
|
92
|
+
#
|
93
|
+
# #### Command-Line Options
|
94
|
+
#
|
95
|
+
# Many command-line options affect entries in hash `IRB.conf`, which in turn
|
96
|
+
# affect the initial configuration of the IRB session.
|
97
|
+
#
|
98
|
+
# Details of the options are described in the relevant subsections below.
|
99
|
+
#
|
100
|
+
# A cursory list of the IRB command-line options may be seen in the [help
|
101
|
+
# message](https://raw.githubusercontent.com/ruby/irb/master/lib/irb/lc/help-message),
|
102
|
+
# which is also displayed if you use command-line option `--help`.
|
103
|
+
#
|
104
|
+
# If you are interested in a specific option, consult the
|
105
|
+
# [index](rdoc-ref:doc/irb/indexes.md@Index+of+Command-Line+Options).
|
106
|
+
#
|
107
|
+
# #### Command-Line Arguments
|
108
|
+
#
|
109
|
+
# Command-line arguments are passed to IRB in array `ARGV`:
|
110
|
+
#
|
111
|
+
# $ irb --noscript Foo Bar Baz
|
112
|
+
# irb(main):001> ARGV
|
113
|
+
# => ["Foo", "Bar", "Baz"]
|
114
|
+
# irb(main):002> exit
|
115
|
+
# $
|
116
|
+
#
|
117
|
+
# Command-line option `--` causes everything that follows to be treated as
|
118
|
+
# arguments, even those that look like options:
|
119
|
+
#
|
120
|
+
# $ irb --noscript -- --noscript -- Foo Bar Baz
|
121
|
+
# irb(main):001> ARGV
|
122
|
+
# => ["--noscript", "--", "Foo", "Bar", "Baz"]
|
123
|
+
# irb(main):002> exit
|
124
|
+
# $
|
125
|
+
#
|
126
|
+
# ### Configuration File
|
127
|
+
#
|
128
|
+
# You can initialize IRB via a *configuration file*.
|
129
|
+
#
|
130
|
+
# If command-line option `-f` is given, no configuration file is looked for.
|
131
|
+
#
|
132
|
+
# Otherwise, IRB reads and interprets a configuration file if one is available.
|
133
|
+
#
|
134
|
+
# The configuration file can contain any Ruby code, and can usefully include
|
135
|
+
# user code that:
|
136
|
+
#
|
137
|
+
# * Can then be debugged in IRB.
|
138
|
+
# * Configures IRB itself.
|
139
|
+
# * Requires or loads files.
|
140
|
+
#
|
141
|
+
#
|
142
|
+
# The path to the configuration file is the first found among:
|
143
|
+
#
|
144
|
+
# * The value of variable `$IRBRC`, if defined.
|
145
|
+
# * The value of variable `$XDG_CONFIG_HOME/irb/irbrc`, if defined.
|
146
|
+
# * File `$HOME/.irbrc`, if it exists.
|
147
|
+
# * File `$HOME/.config/irb/irbrc`, if it exists.
|
148
|
+
# * File `.irbrc` in the current directory, if it exists.
|
149
|
+
# * File `irb.rc` in the current directory, if it exists.
|
150
|
+
# * File `_irbrc` in the current directory, if it exists.
|
151
|
+
# * File `$irbrc` in the current directory, if it exists.
|
152
|
+
#
|
153
|
+
#
|
154
|
+
# If the search fails, there is no configuration file.
|
155
|
+
#
|
156
|
+
# If the search succeeds, the configuration file is read as Ruby code, and so
|
157
|
+
# can contain any Ruby programming you like.
|
158
|
+
#
|
159
|
+
# Method `conf.rc?` returns `true` if a configuration file was read, `false`
|
160
|
+
# otherwise. Hash entry `IRB.conf[:RC]` also contains that value.
|
161
|
+
#
|
162
|
+
# ### Hash `IRB.conf`
|
163
|
+
#
|
164
|
+
# The initial entries in hash `IRB.conf` are determined by:
|
165
|
+
#
|
166
|
+
# * Default values.
|
167
|
+
# * Command-line options, which may override defaults.
|
168
|
+
# * Direct assignments in the configuration file.
|
169
|
+
#
|
170
|
+
#
|
171
|
+
# You can see the hash by typing `IRB.conf`.
|
172
|
+
#
|
173
|
+
# Details of the entries' meanings are described in the relevant subsections
|
174
|
+
# below.
|
175
|
+
#
|
176
|
+
# If you are interested in a specific entry, consult the
|
177
|
+
# [index](rdoc-ref:doc/irb/indexes.md@Index+of+IRB.conf+Entries).
|
178
|
+
#
|
179
|
+
# ### Notes on Initialization Precedence
|
180
|
+
#
|
181
|
+
# * Any conflict between an entry in hash `IRB.conf` and a command-line option
|
182
|
+
# is resolved in favor of the hash entry.
|
183
|
+
# * Hash `IRB.conf` affects the context only once, when the configuration file
|
184
|
+
# is interpreted; any subsequent changes to it do not affect the context and
|
185
|
+
# are therefore essentially meaningless.
|
186
|
+
#
|
187
|
+
#
|
188
|
+
# ### Initialization Script
|
189
|
+
#
|
190
|
+
# By default, the first command-line argument (after any options) is the path to
|
191
|
+
# a Ruby initialization script.
|
192
|
+
#
|
193
|
+
# IRB reads the initialization script and puts its content onto the IRB shell,
|
194
|
+
# just as if it were user-typed commands.
|
195
|
+
#
|
196
|
+
# Command-line option `--noscript` causes the first command-line argument to be
|
197
|
+
# treated as an ordinary argument (instead of an initialization script);
|
198
|
+
# `--script` is the default.
|
199
|
+
#
|
200
|
+
# ## Input
|
201
|
+
#
|
202
|
+
# This section describes the features that allow you to change the way IRB input
|
203
|
+
# works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
|
204
|
+
#
|
205
|
+
# ### Input Command History
|
206
|
+
#
|
207
|
+
# By default, IRB stores a history of up to 1000 input commands in a file named
|
208
|
+
# `.irb_history`. The history file will be in the same directory as the
|
209
|
+
# [configuration file](rdoc-ref:IRB@Configuration+File) if one is found, or in
|
210
|
+
# `~/` otherwise.
|
211
|
+
#
|
212
|
+
# A new IRB session creates the history file if it does not exist, and appends
|
213
|
+
# to the file if it does exist.
|
214
|
+
#
|
215
|
+
# You can change the filepath by adding to your configuration file:
|
216
|
+
# `IRB.conf[:HISTORY_FILE] = *filepath*`, where *filepath* is a string filepath.
|
217
|
+
#
|
218
|
+
# During the session, method `conf.history_file` returns the filepath, and
|
219
|
+
# method `conf.history_file = *new_filepath*` copies the history to the file at
|
220
|
+
# *new_filepath*, which becomes the history file for the session.
|
221
|
+
#
|
222
|
+
# You can change the number of commands saved by adding to your configuration
|
223
|
+
# file: `IRB.conf[:SAVE_HISTORY] = *n*`, wheHISTORY_FILEre *n* is one of:
|
224
|
+
#
|
225
|
+
# * Positive integer: the number of commands to be saved,
|
226
|
+
# * Zero: all commands are to be saved.
|
227
|
+
# * `nil`: no commands are to be saved,.
|
228
|
+
#
|
229
|
+
#
|
230
|
+
# During the session, you can use methods `conf.save_history` or
|
231
|
+
# `conf.save_history=` to retrieve or change the count.
|
232
|
+
#
|
233
|
+
# ### Command Aliases
|
234
|
+
#
|
235
|
+
# By default, IRB defines several command aliases:
|
236
|
+
#
|
237
|
+
# irb(main):001> conf.command_aliases
|
238
|
+
# => {:"$"=>:show_source, :"@"=>:whereami}
|
239
|
+
#
|
240
|
+
# You can change the initial aliases in the configuration file with:
|
241
|
+
#
|
242
|
+
# IRB.conf[:COMMAND_ALIASES] = {foo: :show_source, bar: :whereami}
|
243
|
+
#
|
244
|
+
# You can replace the current aliases at any time with configuration method
|
245
|
+
# `conf.command_aliases=`; Because `conf.command_aliases` is a hash, you can
|
246
|
+
# modify it.
|
247
|
+
#
|
248
|
+
# ### End-of-File
|
249
|
+
#
|
250
|
+
# By default, `IRB.conf[:IGNORE_EOF]` is `false`, which means that typing the
|
251
|
+
# end-of-file character `Ctrl-D` causes the session to exit.
|
252
|
+
#
|
253
|
+
# You can reverse that behavior by adding `IRB.conf[:IGNORE_EOF] = true` to the
|
254
|
+
# configuration file.
|
255
|
+
#
|
256
|
+
# During the session, method `conf.ignore_eof?` returns the setting, and method
|
257
|
+
# `conf.ignore_eof = *boolean*` sets it.
|
258
|
+
#
|
259
|
+
# ### SIGINT
|
260
|
+
#
|
261
|
+
# By default, `IRB.conf[:IGNORE_SIGINT]` is `true`, which means that typing the
|
262
|
+
# interrupt character `Ctrl-C` causes the session to exit.
|
263
|
+
#
|
264
|
+
# You can reverse that behavior by adding `IRB.conf[:IGNORE_SIGING] = false` to
|
265
|
+
# the configuration file.
|
266
|
+
#
|
267
|
+
# During the session, method `conf.ignore_siging?` returns the setting, and
|
268
|
+
# method `conf.ignore_sigint = *boolean*` sets it.
|
269
|
+
#
|
270
|
+
# ### Automatic Completion
|
271
|
+
#
|
272
|
+
# By default, IRB enables [automatic
|
273
|
+
# completion](https://en.wikipedia.org/wiki/Autocomplete#In_command-line_interpr
|
274
|
+
# eters):
|
275
|
+
#
|
276
|
+
# You can disable it by either of these:
|
277
|
+
#
|
278
|
+
# * Adding `IRB.conf[:USE_AUTOCOMPLETE] = false` to the configuration file.
|
279
|
+
# * Giving command-line option `--noautocomplete` (`--autocomplete` is the
|
280
|
+
# default).
|
281
|
+
#
|
282
|
+
#
|
283
|
+
# Method `conf.use_autocomplete?` returns `true` if automatic completion is
|
284
|
+
# enabled, `false` otherwise.
|
285
|
+
#
|
286
|
+
# The setting may not be changed during the session.
|
287
|
+
#
|
288
|
+
# ### Automatic Indentation
|
289
|
+
#
|
290
|
+
# By default, IRB automatically indents lines of code to show structure (e.g.,
|
291
|
+
# it indent the contents of a block).
|
292
|
+
#
|
293
|
+
# The current setting is returned by the configuration method
|
294
|
+
# `conf.auto_indent_mode`.
|
295
|
+
#
|
296
|
+
# The default initial setting is `true`:
|
297
|
+
#
|
298
|
+
# irb(main):001> conf.auto_indent_mode
|
299
|
+
# => true
|
300
|
+
# irb(main):002* Dir.entries('.').select do |entry|
|
301
|
+
# irb(main):003* entry.start_with?('R')
|
302
|
+
# irb(main):004> end
|
303
|
+
# => ["README.md", "Rakefile"]
|
304
|
+
#
|
305
|
+
# You can change the initial setting in the configuration file with:
|
132
306
|
#
|
133
307
|
# IRB.conf[:AUTO_INDENT] = false
|
134
308
|
#
|
135
|
-
#
|
309
|
+
# Note that the *current* setting *may not* be changed in the IRB session.
|
310
|
+
#
|
311
|
+
# ### Input Method
|
312
|
+
#
|
313
|
+
# The IRB input method determines how command input is to be read; by default,
|
314
|
+
# the input method for a session is IRB::RelineInputMethod. Unless the
|
315
|
+
# value of the TERM environment variable is 'dumb', in which case the
|
316
|
+
# most simplistic input method is used.
|
317
|
+
#
|
318
|
+
# You can set the input method by:
|
319
|
+
#
|
320
|
+
# * Adding to the configuration file:
|
321
|
+
#
|
322
|
+
# * `IRB.conf[:USE_SINGLELINE] = true` or `IRB.conf[:USE_MULTILINE]=
|
323
|
+
# false` sets the input method to IRB::ReadlineInputMethod.
|
324
|
+
# * `IRB.conf[:USE_SINGLELINE] = false` or `IRB.conf[:USE_MULTILINE] =
|
325
|
+
# true` sets the input method to IRB::RelineInputMethod.
|
326
|
+
#
|
327
|
+
#
|
328
|
+
# * Giving command-line options:
|
329
|
+
#
|
330
|
+
# * `--singleline` or `--nomultiline` sets the input method to
|
331
|
+
# IRB::ReadlineInputMethod.
|
332
|
+
# * `--nosingleline` or `--multiline` sets the input method to
|
333
|
+
# IRB::RelineInputMethod.
|
334
|
+
# * `--nosingleline` together with `--nomultiline` sets the
|
335
|
+
# input to IRB::StdioInputMethod.
|
336
|
+
#
|
337
|
+
#
|
338
|
+
# Method `conf.use_multiline?` and its synonym `conf.use_reline` return:
|
339
|
+
#
|
340
|
+
# * `true` if option `--multiline` was given.
|
341
|
+
# * `false` if option `--nomultiline` was given.
|
342
|
+
# * `nil` if neither was given.
|
343
|
+
#
|
344
|
+
#
|
345
|
+
# Method `conf.use_singleline?` and its synonym `conf.use_readline` return:
|
346
|
+
#
|
347
|
+
# * `true` if option `--singleline` was given.
|
348
|
+
# * `false` if option `--nosingleline` was given.
|
349
|
+
# * `nil` if neither was given.
|
350
|
+
#
|
351
|
+
#
|
352
|
+
# ## Output
|
353
|
+
#
|
354
|
+
# This section describes the features that allow you to change the way IRB
|
355
|
+
# output works; see also [Input and Output](rdoc-ref:IRB@Input+and+Output).
|
356
|
+
#
|
357
|
+
# ### Return-Value Printing (Echoing)
|
358
|
+
#
|
359
|
+
# By default, IRB prints (echoes) the values returned by all input commands.
|
360
|
+
#
|
361
|
+
# You can change the initial behavior and suppress all echoing by:
|
362
|
+
#
|
363
|
+
# * Adding to the configuration file: `IRB.conf[:ECHO] = false`. (The default
|
364
|
+
# value for this entry is `nil`, which means the same as `true`.)
|
365
|
+
# * Giving command-line option `--noecho`. (The default is `--echo`.)
|
366
|
+
#
|
367
|
+
#
|
368
|
+
# During the session, you can change the current setting with configuration
|
369
|
+
# method `conf.echo=` (set to `true` or `false`).
|
370
|
+
#
|
371
|
+
# As stated above, by default IRB prints the values returned by all input
|
372
|
+
# commands; but IRB offers special treatment for values returned by assignment
|
373
|
+
# statements, which may be:
|
374
|
+
#
|
375
|
+
# * Printed with truncation (to fit on a single line of output), which is the
|
376
|
+
# default; an ellipsis (`...` is suffixed, to indicate the truncation):
|
377
|
+
#
|
378
|
+
# irb(main):001> x = 'abc' * 100
|
379
|
+
#
|
380
|
+
#
|
381
|
+
# > "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc...
|
382
|
+
#
|
383
|
+
# * Printed in full (regardless of the length).
|
384
|
+
# * Suppressed (not printed at all)
|
385
|
+
#
|
386
|
+
#
|
387
|
+
# You can change the initial behavior by:
|
388
|
+
#
|
389
|
+
# * Adding to the configuration file: `IRB.conf[:ECHO_ON_ASSIGNMENT] = false`.
|
390
|
+
# (The default value for this entry is `niL`, which means the same as
|
391
|
+
# `:truncate`.)
|
392
|
+
# * Giving command-line option `--noecho-on-assignment` or
|
393
|
+
# `--echo-on-assignment`. (The default is `--truncate-echo-on-assignment`.)
|
394
|
+
#
|
395
|
+
#
|
396
|
+
# During the session, you can change the current setting with configuration
|
397
|
+
# method `conf.echo_on_assignment=` (set to `true`, `false`, or `:truncate`).
|
136
398
|
#
|
137
|
-
#
|
399
|
+
# By default, IRB formats returned values by calling method `inspect`.
|
138
400
|
#
|
139
|
-
#
|
401
|
+
# You can change the initial behavior by:
|
140
402
|
#
|
141
|
-
#
|
403
|
+
# * Adding to the configuration file: `IRB.conf[:INSPECT_MODE] = false`. (The
|
404
|
+
# default value for this entry is `true`.)
|
405
|
+
# * Giving command-line option `--noinspect`. (The default is `--inspect`.)
|
142
406
|
#
|
143
|
-
# By default, irb will store the last 1000 commands you used in
|
144
|
-
# <code>IRB.conf[:HISTORY_FILE]</code> (<code>~/.irb_history</code> by default).
|
145
407
|
#
|
146
|
-
#
|
408
|
+
# During the session, you can change the setting using method
|
409
|
+
# `conf.inspect_mode=`.
|
147
410
|
#
|
148
|
-
#
|
411
|
+
# ### Multiline Output
|
149
412
|
#
|
150
|
-
#
|
413
|
+
# By default, IRB prefixes a newline to a multiline response.
|
151
414
|
#
|
152
|
-
#
|
153
|
-
# but can be turned on to be stored with this +.irbrc+ setting:
|
415
|
+
# You can change the initial default value by adding to the configuration file:
|
154
416
|
#
|
155
|
-
# IRB.conf[:
|
417
|
+
# IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] = false
|
156
418
|
#
|
157
|
-
#
|
158
|
-
#
|
419
|
+
# During a session, you can retrieve or set the value using methods
|
420
|
+
# `conf.newline_before_multiline_output?` and
|
421
|
+
# `conf.newline_before_multiline_output=`.
|
159
422
|
#
|
160
|
-
#
|
423
|
+
# Examples:
|
161
424
|
#
|
162
|
-
#
|
425
|
+
# irb(main):001> conf.inspect_mode = false
|
426
|
+
# => false
|
427
|
+
# irb(main):002> "foo\nbar"
|
428
|
+
# =>
|
429
|
+
# foo
|
430
|
+
# bar
|
431
|
+
# irb(main):003> conf.newline_before_multiline_output = false
|
432
|
+
# => false
|
433
|
+
# irb(main):004> "foo\nbar"
|
434
|
+
# => foo
|
435
|
+
# bar
|
163
436
|
#
|
164
|
-
#
|
437
|
+
# ### Evaluation History
|
165
438
|
#
|
166
|
-
#
|
439
|
+
# By default, IRB saves no history of evaluations (returned values), and the
|
440
|
+
# related methods `conf.eval_history`, `_`, and `__` are undefined.
|
167
441
|
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
442
|
+
# You can turn on that history, and set the maximum number of evaluations to be
|
443
|
+
# stored:
|
444
|
+
#
|
445
|
+
# * In the configuration file: add `IRB.conf[:EVAL_HISTORY] = *n*`. (Examples
|
446
|
+
# below assume that we've added `IRB.conf[:EVAL_HISTORY] = 5`.)
|
447
|
+
# * In the session (at any time): `conf.eval_history = *n*`.
|
448
|
+
#
|
449
|
+
#
|
450
|
+
# If `n` is zero, all evaluation history is stored.
|
451
|
+
#
|
452
|
+
# Doing either of the above:
|
453
|
+
#
|
454
|
+
# * Sets the maximum size of the evaluation history; defines method
|
455
|
+
# `conf.eval_history`, which returns the maximum size `n` of the evaluation
|
456
|
+
# history:
|
457
|
+
#
|
458
|
+
# irb(main):001> conf.eval_history = 5
|
459
|
+
# => 5
|
460
|
+
# irb(main):002> conf.eval_history
|
461
|
+
# => 5
|
462
|
+
#
|
463
|
+
# * Defines variable `_`, which contains the most recent evaluation, or `nil`
|
464
|
+
# if none; same as method `conf.last_value`:
|
465
|
+
#
|
466
|
+
# irb(main):003> _
|
467
|
+
# => 5
|
468
|
+
# irb(main):004> :foo
|
469
|
+
# => :foo
|
470
|
+
# irb(main):005> :bar
|
471
|
+
# => :bar
|
472
|
+
# irb(main):006> _
|
473
|
+
# => :bar
|
474
|
+
# irb(main):007> _
|
475
|
+
# => :bar
|
476
|
+
#
|
477
|
+
# * Defines variable `__`:
|
478
|
+
#
|
479
|
+
# * `__` unadorned: contains all evaluation history:
|
480
|
+
#
|
481
|
+
# irb(main):008> :foo
|
482
|
+
# => :foo
|
483
|
+
# irb(main):009> :bar
|
484
|
+
# => :bar
|
485
|
+
# irb(main):010> :baz
|
486
|
+
# => :baz
|
487
|
+
# irb(main):011> :bat
|
488
|
+
# => :bat
|
489
|
+
# irb(main):012> :bam
|
490
|
+
# => :bam
|
491
|
+
# irb(main):013> __
|
492
|
+
# =>
|
493
|
+
# 9 :bar
|
494
|
+
# 10 :baz
|
495
|
+
# 11 :bat
|
496
|
+
# 12 :bam
|
497
|
+
# irb(main):014> __
|
498
|
+
# =>
|
499
|
+
# 10 :baz
|
500
|
+
# 11 :bat
|
501
|
+
# 12 :bam
|
502
|
+
# 13 ...self-history...
|
503
|
+
#
|
504
|
+
# Note that when the evaluation is multiline, it is displayed
|
505
|
+
# differently.
|
506
|
+
#
|
507
|
+
# * `__[`*m*`]`:
|
508
|
+
#
|
509
|
+
# * Positive *m*: contains the evaluation for the given line number,
|
510
|
+
# or `nil` if that line number is not in the evaluation history:
|
511
|
+
#
|
512
|
+
# irb(main):015> __[12]
|
513
|
+
# => :bam
|
514
|
+
# irb(main):016> __[1]
|
515
|
+
# => nil
|
516
|
+
#
|
517
|
+
# * Negative *m*: contains the `mth`-from-end evaluation, or `nil` if
|
518
|
+
# that evaluation is not in the evaluation history:
|
519
|
+
#
|
520
|
+
# irb(main):017> __[-3]
|
521
|
+
# => :bam
|
522
|
+
# irb(main):018> __[-13]
|
523
|
+
# => nil
|
524
|
+
#
|
525
|
+
# * Zero *m*: contains `nil`:
|
526
|
+
#
|
527
|
+
# irb(main):019> __[0]
|
528
|
+
# => nil
|
529
|
+
#
|
530
|
+
#
|
531
|
+
#
|
532
|
+
#
|
533
|
+
# ### Prompt and Return Formats
|
534
|
+
#
|
535
|
+
# By default, IRB uses the prompt and return value formats defined in its
|
536
|
+
# `:DEFAULT` prompt mode.
|
537
|
+
#
|
538
|
+
# #### The Default Prompt and Return Format
|
539
|
+
#
|
540
|
+
# The default prompt and return values look like this:
|
541
|
+
#
|
542
|
+
# irb(main):001> 1 + 1
|
543
|
+
# => 2
|
544
|
+
# irb(main):002> 2 + 2
|
545
|
+
# => 4
|
546
|
+
#
|
547
|
+
# The prompt includes:
|
548
|
+
#
|
549
|
+
# * The name of the running program (`irb`); see [IRB
|
550
|
+
# Name](rdoc-ref:IRB@IRB+Name).
|
551
|
+
# * The name of the current session (`main`); See [IRB
|
552
|
+
# Sessions](rdoc-ref:IRB@IRB+Sessions).
|
553
|
+
# * A 3-digit line number (1-based).
|
554
|
+
#
|
555
|
+
#
|
556
|
+
# The default prompt actually defines three formats:
|
557
|
+
#
|
558
|
+
# * One for most situations (as above):
|
559
|
+
#
|
560
|
+
# irb(main):003> Dir
|
561
|
+
# => Dir
|
562
|
+
#
|
563
|
+
# * One for when the typed command is a statement continuation (adds trailing
|
564
|
+
# asterisk):
|
565
|
+
#
|
566
|
+
# irb(main):004* Dir.
|
567
|
+
#
|
568
|
+
# * One for when the typed command is a string continuation (adds trailing
|
569
|
+
# single-quote):
|
570
|
+
#
|
571
|
+
# irb(main):005' Dir.entries('.
|
572
|
+
#
|
573
|
+
#
|
574
|
+
# You can see the prompt change as you type the characters in the following:
|
575
|
+
#
|
576
|
+
# irb(main):001* Dir.entries('.').select do |entry|
|
577
|
+
# irb(main):002* entry.start_with?('R')
|
578
|
+
# irb(main):003> end
|
579
|
+
# => ["README.md", "Rakefile"]
|
580
|
+
#
|
581
|
+
# #### Pre-Defined Prompts
|
582
|
+
#
|
583
|
+
# IRB has several pre-defined prompts, stored in hash `IRB.conf[:PROMPT]`:
|
584
|
+
#
|
585
|
+
# irb(main):001> IRB.conf[:PROMPT].keys
|
586
|
+
# => [:NULL, :DEFAULT, :CLASSIC, :SIMPLE, :INF_RUBY, :XMP]
|
587
|
+
#
|
588
|
+
# To see the full data for these, type `IRB.conf[:PROMPT]`.
|
589
|
+
#
|
590
|
+
# Most of these prompt definitions include specifiers that represent values like
|
591
|
+
# the IRB name, session name, and line number; see [Prompt
|
592
|
+
# Specifiers](rdoc-ref:IRB@Prompt+Specifiers).
|
593
|
+
#
|
594
|
+
# You can change the initial prompt and return format by:
|
595
|
+
#
|
596
|
+
# * Adding to the configuration file: `IRB.conf[:PROMPT] = *mode*` where
|
597
|
+
# *mode* is the symbol name of a prompt mode.
|
598
|
+
# * Giving a command-line option:
|
599
|
+
#
|
600
|
+
# * `--prompt *mode*`: sets the prompt mode to *mode*. where *mode* is the
|
601
|
+
# symbol name of a prompt mode.
|
602
|
+
# * `--simple-prompt` or `--sample-book-mode`: sets the prompt mode to
|
603
|
+
# `:SIMPLE`.
|
604
|
+
# * `--inf-ruby-mode`: sets the prompt mode to `:INF_RUBY` and suppresses
|
605
|
+
# both `--multiline` and `--singleline`.
|
606
|
+
# * `--noprompt`: suppresses prompting; does not affect echoing.
|
607
|
+
#
|
608
|
+
#
|
609
|
+
#
|
610
|
+
# You can retrieve or set the current prompt mode with methods
|
611
|
+
#
|
612
|
+
# `conf.prompt_mode` and `conf.prompt_mode=`.
|
613
|
+
#
|
614
|
+
# If you're interested in prompts and return formats other than the defaults,
|
615
|
+
# you might experiment by trying some of the others.
|
616
|
+
#
|
617
|
+
# #### Custom Prompts
|
618
|
+
#
|
619
|
+
# You can also define custom prompts and return formats, which may be done
|
620
|
+
# either in an IRB session or in the configuration file.
|
621
|
+
#
|
622
|
+
# A prompt in IRB actually defines three prompts, as seen above. For simple
|
623
|
+
# custom data, we'll make all three the same:
|
624
|
+
#
|
625
|
+
# irb(main):001* IRB.conf[:PROMPT][:MY_PROMPT] = {
|
626
|
+
# irb(main):002* PROMPT_I: ': ',
|
627
|
+
# irb(main):003* PROMPT_C: ': ',
|
628
|
+
# irb(main):004* PROMPT_S: ': ',
|
629
|
+
# irb(main):005* RETURN: '=> '
|
630
|
+
# irb(main):006> }
|
631
|
+
# => {:PROMPT_I=>": ", :PROMPT_C=>": ", :PROMPT_S=>": ", :RETURN=>"=> "}
|
632
|
+
#
|
633
|
+
# If you define the custom prompt in the configuration file, you can also make
|
634
|
+
# it the current prompt by adding:
|
175
635
|
#
|
176
636
|
# IRB.conf[:PROMPT_MODE] = :MY_PROMPT
|
177
637
|
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
# irb --prompt my-prompt
|
181
|
-
#
|
182
|
-
# Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
|
183
|
-
# prompt specification, some special strings are available:
|
184
|
-
#
|
185
|
-
# %N # command name which is running
|
186
|
-
# %m # to_s of main object (self)
|
187
|
-
# %M # inspect of main object (self)
|
188
|
-
# %l # type of string(", ', /, ]), `]' is inner %w[...]
|
189
|
-
# %NNi # indent level. NN is digits and means as same as printf("%NNd").
|
190
|
-
# # It can be omitted
|
191
|
-
# %NNn # line number.
|
192
|
-
# %% # %
|
193
|
-
#
|
194
|
-
# For instance, the default prompt mode is defined as follows:
|
195
|
-
#
|
196
|
-
# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
|
197
|
-
# :PROMPT_I => "%N(%m):%03n:%i> ",
|
198
|
-
# :PROMPT_N => "%N(%m):%03n:%i> ",
|
199
|
-
# :PROMPT_S => "%N(%m):%03n:%i%l ",
|
200
|
-
# :PROMPT_C => "%N(%m):%03n:%i* ",
|
201
|
-
# :RETURN => "%s\n" # used to printf
|
202
|
-
# }
|
203
|
-
#
|
204
|
-
# irb comes with a number of available modes:
|
205
|
-
#
|
206
|
-
# # :NULL:
|
207
|
-
# # :PROMPT_I:
|
208
|
-
# # :PROMPT_N:
|
209
|
-
# # :PROMPT_S:
|
210
|
-
# # :PROMPT_C:
|
211
|
-
# # :RETURN: |
|
212
|
-
# # %s
|
213
|
-
# # :DEFAULT:
|
214
|
-
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
215
|
-
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
216
|
-
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
217
|
-
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
218
|
-
# # :RETURN: |
|
219
|
-
# # => %s
|
220
|
-
# # :CLASSIC:
|
221
|
-
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
222
|
-
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
223
|
-
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
224
|
-
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
225
|
-
# # :RETURN: |
|
226
|
-
# # %s
|
227
|
-
# # :SIMPLE:
|
228
|
-
# # :PROMPT_I: ! '>> '
|
229
|
-
# # :PROMPT_N: ! '>> '
|
230
|
-
# # :PROMPT_S:
|
231
|
-
# # :PROMPT_C: ! '?> '
|
232
|
-
# # :RETURN: |
|
233
|
-
# # => %s
|
234
|
-
# # :INF_RUBY:
|
235
|
-
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
236
|
-
# # :PROMPT_N:
|
237
|
-
# # :PROMPT_S:
|
238
|
-
# # :PROMPT_C:
|
239
|
-
# # :RETURN: |
|
240
|
-
# # %s
|
241
|
-
# # :AUTO_INDENT: true
|
242
|
-
# # :XMP:
|
243
|
-
# # :PROMPT_I:
|
244
|
-
# # :PROMPT_N:
|
245
|
-
# # :PROMPT_S:
|
246
|
-
# # :PROMPT_C:
|
247
|
-
# # :RETURN: |2
|
248
|
-
# # ==>%s
|
249
|
-
#
|
250
|
-
# == Restrictions
|
251
|
-
#
|
252
|
-
# Because irb evaluates input immediately after it is syntactically complete,
|
253
|
-
# the results may be slightly different than directly using Ruby.
|
254
|
-
#
|
255
|
-
# == IRB Sessions
|
638
|
+
# Regardless of where it's defined, you can make it the current prompt in a
|
639
|
+
# session:
|
256
640
|
#
|
257
|
-
#
|
641
|
+
# conf.prompt_mode = :MY_PROMPT
|
258
642
|
#
|
259
|
-
# You can
|
260
|
-
#
|
643
|
+
# You can view or modify the current prompt data with various configuration
|
644
|
+
# methods:
|
645
|
+
#
|
646
|
+
# * `conf.prompt_mode`, `conf.prompt_mode=`.
|
647
|
+
# * `conf.prompt_c`, `conf.c=`.
|
648
|
+
# * `conf.prompt_i`, `conf.i=`.
|
649
|
+
# * `conf.prompt_s`, `conf.s=`.
|
650
|
+
# * `conf.return_format`, `return_format=`.
|
651
|
+
#
|
652
|
+
#
|
653
|
+
# #### Prompt Specifiers
|
654
|
+
#
|
655
|
+
# A prompt's definition can include specifiers for which certain values are
|
656
|
+
# substituted:
|
657
|
+
#
|
658
|
+
# * `%N`: the name of the running program.
|
659
|
+
# * `%m`: the value of `self.to_s`.
|
660
|
+
# * `%M`: the value of `self.inspect`.
|
661
|
+
# * `%l`: an indication of the type of string; one of `"`, `'`, `/`, `]`.
|
662
|
+
# * `%NNi`: Indentation level. NN is a 2-digit number that specifies the number
|
663
|
+
# of digits of the indentation level (03 will result in 001).
|
664
|
+
# * `%NNn`: Line number. NN is a 2-digit number that specifies the number
|
665
|
+
# of digits of the line number (03 will result in 001).
|
666
|
+
# * `%%`: Literal `%`.
|
667
|
+
#
|
668
|
+
#
|
669
|
+
# ### Verbosity
|
670
|
+
#
|
671
|
+
# By default, IRB verbosity is disabled, which means that output is smaller
|
672
|
+
# rather than larger.
|
673
|
+
#
|
674
|
+
# You can enable verbosity by:
|
675
|
+
#
|
676
|
+
# * Adding to the configuration file: `IRB.conf[:VERBOSE] = true` (the default
|
677
|
+
# is `nil`).
|
678
|
+
# * Giving command-line options `--verbose` (the default is `--noverbose`).
|
679
|
+
#
|
680
|
+
#
|
681
|
+
# During a session, you can retrieve or set verbosity with methods
|
682
|
+
# `conf.verbose` and `conf.verbose=`.
|
683
|
+
#
|
684
|
+
# ### Help
|
685
|
+
#
|
686
|
+
# Command-line option `--version` causes IRB to print its help text and exit.
|
687
|
+
#
|
688
|
+
# ### Version
|
689
|
+
#
|
690
|
+
# Command-line option `--version` causes IRB to print its version text and exit.
|
691
|
+
#
|
692
|
+
# ## Input and Output
|
693
|
+
#
|
694
|
+
# ### Color Highlighting
|
695
|
+
#
|
696
|
+
# By default, IRB color highlighting is enabled, and is used for both:
|
697
|
+
#
|
698
|
+
# * Input: As you type, IRB reads the typed characters and highlights elements
|
699
|
+
# that it recognizes; it also highlights errors such as mismatched
|
700
|
+
# parentheses.
|
701
|
+
# * Output: IRB highlights syntactical elements.
|
702
|
+
#
|
703
|
+
#
|
704
|
+
# You can disable color highlighting by:
|
705
|
+
#
|
706
|
+
# * Adding to the configuration file: `IRB.conf[:USE_COLORIZE] = false` (the
|
707
|
+
# default value is `true`).
|
708
|
+
# * Giving command-line option `--nocolorize`
|
709
|
+
#
|
710
|
+
#
|
711
|
+
# ## Debugging
|
712
|
+
#
|
713
|
+
# Command-line option `-d` sets variables `$VERBOSE` and `$DEBUG` to `true`;
|
714
|
+
# these have no effect on IRB output.
|
715
|
+
#
|
716
|
+
# ### Warnings
|
717
|
+
#
|
718
|
+
# Command-line option `-w` suppresses warnings.
|
719
|
+
#
|
720
|
+
# Command-line option `-W[*level*]` sets warning level;
|
721
|
+
#
|
722
|
+
# * 0=silence
|
723
|
+
# * 1=medium
|
724
|
+
# * 2=verbose
|
725
|
+
#
|
726
|
+
# ## Other Features
|
727
|
+
#
|
728
|
+
# ### Load Modules
|
729
|
+
#
|
730
|
+
# You can specify the names of modules that are to be required at startup.
|
731
|
+
#
|
732
|
+
# Array `conf.load_modules` determines the modules (if any) that are to be
|
733
|
+
# required during session startup. The array is used only during session
|
734
|
+
# startup, so the initial value is the only one that counts.
|
735
|
+
#
|
736
|
+
# The default initial value is `[]` (load no modules):
|
737
|
+
#
|
738
|
+
# irb(main):001> conf.load_modules
|
739
|
+
# => []
|
740
|
+
#
|
741
|
+
# You can set the default initial value via:
|
742
|
+
#
|
743
|
+
# * Command-line option `-r`
|
744
|
+
#
|
745
|
+
# $ irb -r csv -r json
|
746
|
+
# irb(main):001> conf.load_modules
|
747
|
+
# => ["csv", "json"]
|
748
|
+
#
|
749
|
+
# * Hash entry `IRB.conf[:LOAD_MODULES] = *array*`:
|
750
|
+
#
|
751
|
+
# IRB.conf[:LOAD_MODULES] = %w[csv, json]
|
752
|
+
#
|
753
|
+
#
|
754
|
+
# Note that the configuration file entry overrides the command-line options.
|
755
|
+
#
|
756
|
+
# ### RI Documentation Directories
|
757
|
+
#
|
758
|
+
# You can specify the paths to RI documentation directories that are to be
|
759
|
+
# loaded (in addition to the default directories) at startup; see details about
|
760
|
+
# RI by typing `ri --help`.
|
761
|
+
#
|
762
|
+
# Array `conf.extra_doc_dirs` determines the directories (if any) that are to be
|
763
|
+
# loaded during session startup. The array is used only during session startup,
|
764
|
+
# so the initial value is the only one that counts.
|
765
|
+
#
|
766
|
+
# The default initial value is `[]` (load no extra documentation):
|
767
|
+
#
|
768
|
+
# irb(main):001> conf.extra_doc_dirs
|
769
|
+
# => []
|
770
|
+
#
|
771
|
+
# You can set the default initial value via:
|
772
|
+
#
|
773
|
+
# * Command-line option `--extra_doc_dir`
|
774
|
+
#
|
775
|
+
# $ irb --extra-doc-dir your_doc_dir --extra-doc-dir my_doc_dir
|
776
|
+
# irb(main):001> conf.extra_doc_dirs
|
777
|
+
# => ["your_doc_dir", "my_doc_dir"]
|
778
|
+
#
|
779
|
+
# * Hash entry `IRB.conf[:EXTRA_DOC_DIRS] = *array*`:
|
780
|
+
#
|
781
|
+
# IRB.conf[:EXTRA_DOC_DIRS] = %w[your_doc_dir my_doc_dir]
|
782
|
+
#
|
783
|
+
#
|
784
|
+
# Note that the configuration file entry overrides the command-line options.
|
785
|
+
#
|
786
|
+
# ### IRB Name
|
787
|
+
#
|
788
|
+
# You can specify a name for IRB.
|
789
|
+
#
|
790
|
+
# The default initial value is `'irb'`:
|
791
|
+
#
|
792
|
+
# irb(main):001> conf.irb_name
|
793
|
+
# => "irb"
|
794
|
+
#
|
795
|
+
# You can set the default initial value via hash entry `IRB.conf[:IRB_NAME] =
|
796
|
+
# *string*`:
|
797
|
+
#
|
798
|
+
# IRB.conf[:IRB_NAME] = 'foo'
|
799
|
+
#
|
800
|
+
# ### Application Name
|
801
|
+
#
|
802
|
+
# You can specify an application name for the IRB session.
|
261
803
|
#
|
262
|
-
#
|
804
|
+
# The default initial value is `'irb'`:
|
263
805
|
#
|
264
|
-
#
|
806
|
+
# irb(main):001> conf.ap_name
|
807
|
+
# => "irb"
|
265
808
|
#
|
266
|
-
#
|
267
|
-
#
|
268
|
-
# kill # Kills the session with the given number
|
809
|
+
# You can set the default initial value via hash entry `IRB.conf[:AP_NAME] =
|
810
|
+
# *string*`:
|
269
811
|
#
|
270
|
-
#
|
271
|
-
# exit hooks with IRB.irb_at_exit.
|
812
|
+
# IRB.conf[:AP_NAME] = 'my_ap_name'
|
272
813
|
#
|
273
|
-
#
|
814
|
+
# ### Configuration Monitor
|
274
815
|
#
|
275
|
-
#
|
276
|
-
#
|
277
|
-
# see IrbLoader#source_file
|
278
|
-
# +irb_load+::
|
279
|
-
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
|
280
|
-
# +irb_require+::
|
281
|
-
# Loads the given file similarly to Kernel#require
|
816
|
+
# You can monitor changes to the configuration by assigning a proc to
|
817
|
+
# `IRB.conf[:IRB_RC]` in the configuration file:
|
282
818
|
#
|
283
|
-
#
|
819
|
+
# IRB.conf[:IRB_RC] = proc {|conf| puts conf.class }
|
820
|
+
#
|
821
|
+
# Each time the configuration is changed, that proc is called with argument
|
822
|
+
# `conf`:
|
823
|
+
#
|
824
|
+
# ### Encodings
|
825
|
+
#
|
826
|
+
# Command-line option `-E *ex*[:*in*]` sets initial external (ex) and internal
|
827
|
+
# (in) encodings.
|
828
|
+
#
|
829
|
+
# Command-line option `-U` sets both to UTF-8.
|
830
|
+
#
|
831
|
+
# ### Commands
|
832
|
+
#
|
833
|
+
# Please use the `help` command to see the list of available commands.
|
834
|
+
#
|
835
|
+
# ### IRB Sessions
|
836
|
+
#
|
837
|
+
# IRB has a special feature, that allows you to manage many sessions at once.
|
838
|
+
#
|
839
|
+
# You can create new sessions with Irb.irb, and get a list of current sessions
|
840
|
+
# with the `jobs` command in the prompt.
|
841
|
+
#
|
842
|
+
# #### Configuration
|
284
843
|
#
|
285
844
|
# The command line options, or IRB.conf, specify the default behavior of
|
286
845
|
# Irb.irb.
|
287
846
|
#
|
288
|
-
# On the other hand, each conf in IRB@Command+
|
847
|
+
# On the other hand, each conf in IRB@Command-Line+Options is used to
|
289
848
|
# individually configure IRB.irb.
|
290
849
|
#
|
291
|
-
# If a proc is set for
|
850
|
+
# If a proc is set for `IRB.conf[:IRB_RC]`, its will be invoked after execution
|
292
851
|
# of that proc with the context of the current session as its argument. Each
|
293
852
|
# session can be configured using this mechanism.
|
294
853
|
#
|
295
|
-
#
|
854
|
+
# #### Session variables
|
296
855
|
#
|
297
856
|
# There are a few variables in every Irb session that can come in handy:
|
298
857
|
#
|
299
|
-
#
|
300
|
-
# The value command executed, as a local variable
|
301
|
-
#
|
302
|
-
# The history of evaluated commands. Available only if
|
303
|
-
#
|
304
|
-
#
|
305
|
-
#
|
306
|
-
# Returns the evaluation value at the given line number,
|
307
|
-
#
|
308
|
-
#
|
309
|
-
#
|
310
|
-
#
|
311
|
-
#
|
312
|
-
#
|
313
|
-
#
|
314
|
-
#
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
# # change the active session
|
320
|
-
# irb.1(main):002:0> fg 0
|
321
|
-
# # define class Foo in top-level session
|
322
|
-
# irb(main):002:0> class Foo;end
|
323
|
-
# # invoke a new session with the context of Foo
|
324
|
-
# irb(main):003:0> irb Foo
|
325
|
-
# # define Foo#foo
|
326
|
-
# irb.2(Foo):001:0> def foo
|
327
|
-
# irb.2(Foo):002:1> print 1
|
328
|
-
# irb.2(Foo):003:1> end
|
329
|
-
#
|
330
|
-
# # change the active session
|
331
|
-
# irb.2(Foo):004:0> fg 0
|
332
|
-
# # list open sessions
|
333
|
-
# irb(main):004:0> jobs
|
334
|
-
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
335
|
-
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
336
|
-
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
337
|
-
# # check if Foo#foo is available
|
338
|
-
# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
|
339
|
-
#
|
340
|
-
# # change the active session
|
341
|
-
# irb(main):006:0> fg 2
|
342
|
-
# # define Foo#bar in the context of Foo
|
343
|
-
# irb.2(Foo):005:0> def bar
|
344
|
-
# irb.2(Foo):006:1> print "bar"
|
345
|
-
# irb.2(Foo):007:1> end
|
346
|
-
# irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
|
347
|
-
#
|
348
|
-
# # change the active session
|
349
|
-
# irb.2(Foo):011:0> fg 0
|
350
|
-
# irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
|
351
|
-
# # invoke a new session with the context of f (instance of Foo)
|
352
|
-
# irb(main):008:0> irb f
|
353
|
-
# # list open sessions
|
354
|
-
# irb.3(<Foo:0x4010af3c>):001:0> jobs
|
355
|
-
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
|
356
|
-
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
357
|
-
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
358
|
-
# #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
|
359
|
-
# # evaluate f.foo
|
360
|
-
# irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
|
361
|
-
# # evaluate f.bar
|
362
|
-
# irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
|
363
|
-
# # kill jobs 1, 2, and 3
|
364
|
-
# irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
|
365
|
-
# # list open sessions, should only include main session
|
366
|
-
# irb(main):009:0> jobs
|
367
|
-
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
368
|
-
# # quit irb
|
369
|
-
# irb(main):010:0> exit
|
858
|
+
# `_`
|
859
|
+
# : The value command executed, as a local variable
|
860
|
+
# `__`
|
861
|
+
# : The history of evaluated commands. Available only if
|
862
|
+
# `IRB.conf[:EVAL_HISTORY]` is not `nil` (which is the default). See also
|
863
|
+
# IRB::Context#eval_history= and IRB::History.
|
864
|
+
# `__[line_no]`
|
865
|
+
# : Returns the evaluation value at the given line number, `line_no`. If
|
866
|
+
# `line_no` is a negative, the return value `line_no` many lines before the
|
867
|
+
# most recent return value.
|
868
|
+
#
|
869
|
+
#
|
870
|
+
# ## Restrictions
|
871
|
+
#
|
872
|
+
# Ruby code typed into IRB behaves the same as Ruby code in a file, except that:
|
873
|
+
#
|
874
|
+
# * Because IRB evaluates input immediately after it is syntactically
|
875
|
+
# complete, some results may be slightly different.
|
876
|
+
# * Forking may not be well behaved.
|
877
|
+
#
|
370
878
|
module IRB
|
371
879
|
|
372
880
|
# An exception raised by IRB.irb_abort
|
373
881
|
class Abort < Exception;end
|
374
882
|
|
375
|
-
@CONF = {}
|
376
|
-
|
377
|
-
|
378
|
-
# Displays current configuration.
|
379
|
-
#
|
380
|
-
# Modifying the configuration is achieved by sending a message to IRB.conf.
|
381
|
-
#
|
382
|
-
# See IRB@Configuration for more information.
|
383
|
-
def IRB.conf
|
384
|
-
@CONF
|
385
|
-
end
|
386
|
-
|
387
|
-
# Returns the current version of IRB, including release version and last
|
388
|
-
# updated date.
|
389
|
-
def IRB.version
|
390
|
-
if v = @CONF[:VERSION] then return v end
|
391
|
-
|
392
|
-
@CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
|
393
|
-
end
|
394
|
-
|
395
883
|
# The current IRB::Context of the session, see IRB.conf
|
396
884
|
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
def IRB.CurrentContext
|
885
|
+
# irb
|
886
|
+
# irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
|
887
|
+
# foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
|
888
|
+
def IRB.CurrentContext # :nodoc:
|
401
889
|
IRB.conf[:MAIN_CONTEXT]
|
402
890
|
end
|
403
891
|
|
404
|
-
# Initializes IRB and creates a new Irb.irb object at the
|
892
|
+
# Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
|
405
893
|
def IRB.start(ap_path = nil)
|
406
894
|
STDOUT.sync = true
|
407
895
|
$0 = File::basename(ap_path, ".rb") if ap_path
|
@@ -417,62 +905,48 @@ module IRB
|
|
417
905
|
end
|
418
906
|
|
419
907
|
# Quits irb
|
420
|
-
def IRB.irb_exit(
|
421
|
-
throw :IRB_EXIT,
|
908
|
+
def IRB.irb_exit(*) # :nodoc:
|
909
|
+
throw :IRB_EXIT, false
|
422
910
|
end
|
423
911
|
|
424
912
|
# Aborts then interrupts irb.
|
425
913
|
#
|
426
|
-
# Will raise an Abort exception, or the given
|
427
|
-
def IRB.irb_abort(irb, exception = Abort)
|
914
|
+
# Will raise an Abort exception, or the given `exception`.
|
915
|
+
def IRB.irb_abort(irb, exception = Abort) # :nodoc:
|
428
916
|
irb.context.thread.raise exception, "abort then interrupt!"
|
429
917
|
end
|
430
918
|
|
431
919
|
class Irb
|
432
|
-
ASSIGNMENT_NODE_TYPES = [
|
433
|
-
# Local, instance, global, class, constant, instance, and index assignment:
|
434
|
-
# "foo = bar",
|
435
|
-
# "@foo = bar",
|
436
|
-
# "$foo = bar",
|
437
|
-
# "@@foo = bar",
|
438
|
-
# "::Foo = bar",
|
439
|
-
# "a::Foo = bar",
|
440
|
-
# "Foo = bar"
|
441
|
-
# "foo.bar = 1"
|
442
|
-
# "foo[1] = bar"
|
443
|
-
:assign,
|
444
|
-
|
445
|
-
# Operation assignment:
|
446
|
-
# "foo += bar"
|
447
|
-
# "foo -= bar"
|
448
|
-
# "foo ||= bar"
|
449
|
-
# "foo &&= bar"
|
450
|
-
:opassign,
|
451
|
-
|
452
|
-
# Multiple assignment:
|
453
|
-
# "foo, bar = 1, 2
|
454
|
-
:massign,
|
455
|
-
]
|
456
920
|
# Note: instance and index assignment expressions could also be written like:
|
457
|
-
# "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
|
458
|
-
#
|
459
|
-
#
|
921
|
+
# "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former be
|
922
|
+
# parsed as :assign and echo will be suppressed, but the latter is parsed as a
|
923
|
+
# :method_add_arg and the output won't be suppressed
|
460
924
|
|
461
925
|
PROMPT_MAIN_TRUNCATE_LENGTH = 32
|
462
|
-
PROMPT_MAIN_TRUNCATE_OMISSION = '...'
|
463
|
-
CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
|
926
|
+
PROMPT_MAIN_TRUNCATE_OMISSION = '...'
|
927
|
+
CONTROL_CHARACTERS_PATTERN = "\x00-\x1F"
|
928
|
+
|
929
|
+
# Returns the current context of this irb session
|
930
|
+
attr_reader :context
|
931
|
+
# The lexer used by this irb session
|
932
|
+
attr_accessor :scanner
|
933
|
+
|
934
|
+
attr_reader :from_binding
|
464
935
|
|
465
936
|
# Creates a new irb session
|
466
|
-
def initialize(workspace = nil, input_method = nil)
|
937
|
+
def initialize(workspace = nil, input_method = nil, from_binding: false)
|
938
|
+
@from_binding = from_binding
|
467
939
|
@context = Context.new(self, workspace, input_method)
|
468
|
-
@context.
|
940
|
+
@context.workspace.load_helper_methods_to_main
|
469
941
|
@signal_status = :IN_IRB
|
470
|
-
@scanner = RubyLex.new
|
942
|
+
@scanner = RubyLex.new
|
943
|
+
@line_no = 1
|
471
944
|
end
|
472
945
|
|
473
|
-
# A hook point for `debug` command's
|
946
|
+
# A hook point for `debug` command's breakpoint after :IRB_EXIT as well as its
|
947
|
+
# clean-up
|
474
948
|
def debug_break
|
475
|
-
# it means the debug
|
949
|
+
# it means the debug integration has been activated
|
476
950
|
if defined?(DEBUGGER__) && DEBUGGER__.respond_to?(:capture_frames_without_irb)
|
477
951
|
# after leaving this initial breakpoint, revert the capture_frames patch
|
478
952
|
DEBUGGER__.singleton_class.send(:alias_method, :capture_frames, :capture_frames_without_irb)
|
@@ -481,89 +955,101 @@ module IRB
|
|
481
955
|
end
|
482
956
|
end
|
483
957
|
|
958
|
+
def debug_readline(binding)
|
959
|
+
workspace = IRB::WorkSpace.new(binding)
|
960
|
+
context.replace_workspace(workspace)
|
961
|
+
context.workspace.load_helper_methods_to_main
|
962
|
+
@line_no += 1
|
963
|
+
|
964
|
+
# When users run:
|
965
|
+
# 1. Debugging commands, like `step 2`
|
966
|
+
# 2. Any input that's not irb-command, like `foo = 123`
|
967
|
+
#
|
968
|
+
#
|
969
|
+
# Irb#eval_input will simply return the input, and we need to pass it to the
|
970
|
+
# debugger.
|
971
|
+
input = nil
|
972
|
+
forced_exit = catch(:IRB_EXIT) do
|
973
|
+
if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
|
974
|
+
# Previous IRB session's history has been saved when `Irb#run` is exited We need
|
975
|
+
# to make sure the saved history is not saved again by resetting the counter
|
976
|
+
context.io.reset_history_counter
|
977
|
+
|
978
|
+
begin
|
979
|
+
input = eval_input
|
980
|
+
ensure
|
981
|
+
context.io.save_history
|
982
|
+
end
|
983
|
+
else
|
984
|
+
input = eval_input
|
985
|
+
end
|
986
|
+
false
|
987
|
+
end
|
988
|
+
|
989
|
+
Kernel.exit if forced_exit
|
990
|
+
|
991
|
+
if input&.include?("\n")
|
992
|
+
@line_no += input.count("\n") - 1
|
993
|
+
end
|
994
|
+
|
995
|
+
input
|
996
|
+
end
|
997
|
+
|
484
998
|
def run(conf = IRB.conf)
|
999
|
+
in_nested_session = !!conf[:MAIN_CONTEXT]
|
485
1000
|
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
1001
|
+
prev_context = conf[:MAIN_CONTEXT]
|
486
1002
|
conf[:MAIN_CONTEXT] = context
|
487
1003
|
|
1004
|
+
save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
|
1005
|
+
|
1006
|
+
if save_history
|
1007
|
+
context.io.load_history
|
1008
|
+
end
|
1009
|
+
|
488
1010
|
prev_trap = trap("SIGINT") do
|
489
1011
|
signal_handle
|
490
1012
|
end
|
491
1013
|
|
492
1014
|
begin
|
493
|
-
|
1015
|
+
if defined?(RubyVM.keep_script_lines)
|
1016
|
+
keep_script_lines_backup = RubyVM.keep_script_lines
|
1017
|
+
RubyVM.keep_script_lines = true
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
forced_exit = catch(:IRB_EXIT) do
|
494
1021
|
eval_input
|
495
1022
|
end
|
496
1023
|
ensure
|
1024
|
+
# Do not restore to nil. It will cause IRB crash when used with threads.
|
1025
|
+
IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context
|
1026
|
+
|
1027
|
+
RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines)
|
497
1028
|
trap("SIGINT", prev_trap)
|
498
1029
|
conf[:AT_EXIT].each{|hook| hook.call}
|
1030
|
+
|
1031
|
+
context.io.save_history if save_history
|
1032
|
+
Kernel.exit if forced_exit
|
499
1033
|
end
|
500
1034
|
end
|
501
1035
|
|
502
|
-
# Returns the current context of this irb session
|
503
|
-
attr_reader :context
|
504
|
-
# The lexer used by this irb session
|
505
|
-
attr_accessor :scanner
|
506
|
-
|
507
1036
|
# Evaluates input for this session.
|
508
1037
|
def eval_input
|
509
|
-
|
510
|
-
|ltype, indent, continue, line_no|
|
511
|
-
if ltype
|
512
|
-
f = @context.prompt_s
|
513
|
-
elsif continue
|
514
|
-
f = @context.prompt_c
|
515
|
-
elsif indent > 0
|
516
|
-
f = @context.prompt_n
|
517
|
-
else
|
518
|
-
f = @context.prompt_i
|
519
|
-
end
|
520
|
-
f = "" unless f
|
521
|
-
if @context.prompting?
|
522
|
-
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
523
|
-
else
|
524
|
-
@context.io.prompt = p = ""
|
525
|
-
end
|
526
|
-
if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
|
527
|
-
unless ltype
|
528
|
-
prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
|
529
|
-
ind = prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
530
|
-
indent * 2 - p.size
|
531
|
-
ind += 2 if continue
|
532
|
-
@context.io.prompt = p + " " * ind if ind > 0
|
533
|
-
end
|
534
|
-
end
|
535
|
-
@context.io.prompt
|
536
|
-
end
|
537
|
-
|
538
|
-
@scanner.set_input do
|
539
|
-
signal_status(:IN_INPUT) do
|
540
|
-
if l = @context.io.gets
|
541
|
-
print l if @context.verbose?
|
542
|
-
else
|
543
|
-
if @context.ignore_eof? and @context.io.readable_after_eof?
|
544
|
-
l = "\n"
|
545
|
-
if @context.verbose?
|
546
|
-
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
547
|
-
end
|
548
|
-
else
|
549
|
-
print "\n" if @context.prompting?
|
550
|
-
end
|
551
|
-
end
|
552
|
-
l
|
553
|
-
end
|
554
|
-
end
|
1038
|
+
configure_io
|
555
1039
|
|
556
|
-
|
557
|
-
|
558
|
-
@scanner.each_top_level_statement do |line, line_no|
|
1040
|
+
each_top_level_statement do |statement, line_no|
|
559
1041
|
signal_status(:IN_EVAL) do
|
560
1042
|
begin
|
561
|
-
#
|
562
|
-
|
563
|
-
|
1043
|
+
# If the integration with debugger is activated, we return certain input if it
|
1044
|
+
# should be dealt with by debugger
|
1045
|
+
if @context.with_debugger && statement.should_be_handled_by_debugger?
|
1046
|
+
return statement.code
|
1047
|
+
end
|
564
1048
|
|
565
|
-
|
566
|
-
|
1049
|
+
@context.evaluate(statement, line_no)
|
1050
|
+
|
1051
|
+
if @context.echo? && !statement.suppresses_echo?
|
1052
|
+
if statement.is_assignment?
|
567
1053
|
if @context.echo_on_assignment?
|
568
1054
|
output_value(@context.echo_on_assignment? == :truncate)
|
569
1055
|
end
|
@@ -581,21 +1067,149 @@ module IRB
|
|
581
1067
|
end
|
582
1068
|
end
|
583
1069
|
|
584
|
-
def
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
1070
|
+
def read_input(prompt)
|
1071
|
+
signal_status(:IN_INPUT) do
|
1072
|
+
@context.io.prompt = prompt
|
1073
|
+
if l = @context.io.gets
|
1074
|
+
print l if @context.verbose?
|
1075
|
+
else
|
1076
|
+
if @context.ignore_eof? and @context.io.readable_after_eof?
|
1077
|
+
l = "\n"
|
1078
|
+
if @context.verbose?
|
1079
|
+
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
1080
|
+
end
|
1081
|
+
else
|
1082
|
+
print "\n" if @context.prompting?
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
l
|
590
1086
|
end
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
def readmultiline
|
1090
|
+
prompt = generate_prompt([], false, 0)
|
1091
|
+
|
1092
|
+
# multiline
|
1093
|
+
return read_input(prompt) if @context.io.respond_to?(:check_termination)
|
1094
|
+
|
1095
|
+
# nomultiline
|
1096
|
+
code = +''
|
1097
|
+
line_offset = 0
|
1098
|
+
loop do
|
1099
|
+
line = read_input(prompt)
|
1100
|
+
unless line
|
1101
|
+
return code.empty? ? nil : code
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
code << line
|
1105
|
+
return code if command?(code)
|
591
1106
|
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
1107
|
+
tokens, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
|
1108
|
+
return code if terminated
|
1109
|
+
|
1110
|
+
line_offset += 1
|
1111
|
+
continue = @scanner.should_continue?(tokens)
|
1112
|
+
prompt = generate_prompt(opens, continue, line_offset)
|
596
1113
|
end
|
1114
|
+
end
|
597
1115
|
|
598
|
-
|
1116
|
+
def each_top_level_statement
|
1117
|
+
loop do
|
1118
|
+
code = readmultiline
|
1119
|
+
break unless code
|
1120
|
+
yield build_statement(code), @line_no
|
1121
|
+
@line_no += code.count("\n")
|
1122
|
+
rescue RubyLex::TerminateLineInput
|
1123
|
+
end
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
def build_statement(code)
|
1127
|
+
if code.match?(/\A\n*\z/)
|
1128
|
+
return Statement::EmptyInput.new
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
code.force_encoding(@context.io.encoding)
|
1132
|
+
if (command, arg = parse_command(code))
|
1133
|
+
command_class = Command.load_command(command)
|
1134
|
+
Statement::Command.new(code, command_class, arg)
|
1135
|
+
else
|
1136
|
+
is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables)
|
1137
|
+
Statement::Expression.new(code, is_assignment_expression)
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
def parse_command(code)
|
1142
|
+
command_name, arg = code.strip.split(/\s+/, 2)
|
1143
|
+
return unless code.lines.size == 1 && command_name
|
1144
|
+
|
1145
|
+
arg ||= ''
|
1146
|
+
command = command_name.to_sym
|
1147
|
+
# Command aliases are always command. example: $, @
|
1148
|
+
if (alias_name = @context.command_aliases[command])
|
1149
|
+
return [alias_name, arg]
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
# Check visibility
|
1153
|
+
public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
|
1154
|
+
private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
|
1155
|
+
if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
|
1156
|
+
[command, arg]
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
def command?(code)
|
1161
|
+
!!parse_command(code)
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def configure_io
|
1165
|
+
if @context.io.respond_to?(:check_termination)
|
1166
|
+
@context.io.check_termination do |code|
|
1167
|
+
if Reline::IOGate.in_pasting?
|
1168
|
+
rest = @scanner.check_termination_in_prev_line(code, local_variables: @context.local_variables)
|
1169
|
+
if rest
|
1170
|
+
Reline.delete_text
|
1171
|
+
rest.bytes.reverse_each do |c|
|
1172
|
+
Reline.ungetc(c)
|
1173
|
+
end
|
1174
|
+
true
|
1175
|
+
else
|
1176
|
+
false
|
1177
|
+
end
|
1178
|
+
else
|
1179
|
+
next true if command?(code)
|
1180
|
+
|
1181
|
+
_tokens, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables)
|
1182
|
+
terminated
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
end
|
1186
|
+
if @context.io.respond_to?(:dynamic_prompt)
|
1187
|
+
@context.io.dynamic_prompt do |lines|
|
1188
|
+
tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables)
|
1189
|
+
line_results = IRB::NestingParser.parse_by_line(tokens)
|
1190
|
+
tokens_until_line = []
|
1191
|
+
line_results.map.with_index do |(line_tokens, _prev_opens, next_opens, _min_depth), line_num_offset|
|
1192
|
+
line_tokens.each do |token, _s|
|
1193
|
+
# Avoid appending duplicated token. Tokens that include "n" like multiline
|
1194
|
+
# tstring_content can exist in multiple lines.
|
1195
|
+
tokens_until_line << token if token != tokens_until_line.last
|
1196
|
+
end
|
1197
|
+
continue = @scanner.should_continue?(tokens_until_line)
|
1198
|
+
generate_prompt(next_opens, continue, line_num_offset)
|
1199
|
+
end
|
1200
|
+
end
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
if @context.io.respond_to?(:auto_indent) and @context.auto_indent_mode
|
1204
|
+
@context.io.auto_indent do |lines, line_index, byte_pointer, is_newline|
|
1205
|
+
next nil if lines == [nil] # Workaround for exit IRB with CTRL+d
|
1206
|
+
next nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/)
|
1207
|
+
|
1208
|
+
code = lines[0..line_index].map { |l| "#{l}\n" }.join
|
1209
|
+
tokens = RubyLex.ripper_lex_without_warning(code, local_variables: @context.local_variables)
|
1210
|
+
@scanner.process_indent_level(tokens, lines, line_index, is_newline)
|
1211
|
+
end
|
1212
|
+
end
|
599
1213
|
end
|
600
1214
|
|
601
1215
|
def convert_invalid_byte_sequence(str, enc)
|
@@ -628,60 +1242,75 @@ module IRB
|
|
628
1242
|
end
|
629
1243
|
|
630
1244
|
def handle_exception(exc)
|
631
|
-
if exc.backtrace
|
1245
|
+
if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
632
1246
|
!(SyntaxError === exc) && !(EncodingError === exc)
|
633
1247
|
# The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno.
|
634
1248
|
irb_bug = true
|
635
1249
|
else
|
636
1250
|
irb_bug = false
|
637
|
-
|
1251
|
+
# To support backtrace filtering while utilizing Exception#full_message, we need to clone
|
1252
|
+
# the exception to avoid modifying the original exception's backtrace.
|
1253
|
+
exc = exc.clone
|
1254
|
+
filtered_backtrace = exc.backtrace.map { |l| @context.workspace.filter_backtrace(l) }.compact
|
1255
|
+
backtrace_filter = IRB.conf[:BACKTRACE_FILTER]
|
638
1256
|
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
if STDOUT.tty?
|
643
|
-
message = exc.full_message(order: :bottom)
|
644
|
-
order = :bottom
|
1257
|
+
if backtrace_filter
|
1258
|
+
if backtrace_filter.respond_to?(:call)
|
1259
|
+
filtered_backtrace = backtrace_filter.call(filtered_backtrace)
|
645
1260
|
else
|
646
|
-
|
647
|
-
order = :top
|
1261
|
+
warn "IRB.conf[:BACKTRACE_FILTER] #{backtrace_filter} should respond to `call` method"
|
648
1262
|
end
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
exc.set_backtrace(filtered_backtrace)
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
highlight = Color.colorable?
|
1269
|
+
|
1270
|
+
order =
|
1271
|
+
if RUBY_VERSION < '3.0.0'
|
1272
|
+
STDOUT.tty? ? :bottom : :top
|
649
1273
|
else # '3.0.0' <= RUBY_VERSION
|
650
|
-
|
651
|
-
order = :top
|
1274
|
+
:top
|
652
1275
|
end
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
1276
|
+
|
1277
|
+
message = exc.full_message(order: order, highlight: highlight)
|
1278
|
+
message = convert_invalid_byte_sequence(message, exc.message.encoding)
|
1279
|
+
message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
|
1280
|
+
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
|
1281
|
+
case order
|
1282
|
+
when :top
|
1283
|
+
lines = m.split("\n")
|
1284
|
+
when :bottom
|
1285
|
+
lines = m.split("\n").reverse
|
1286
|
+
end
|
1287
|
+
unless irb_bug
|
1288
|
+
if lines.size > @context.back_trace_limit
|
1289
|
+
omit = lines.size - @context.back_trace_limit
|
1290
|
+
lines = lines[0..(@context.back_trace_limit - 1)]
|
1291
|
+
lines << "\t... %d levels..." % omit
|
669
1292
|
end
|
670
|
-
|
671
|
-
|
672
|
-
}
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
1293
|
+
end
|
1294
|
+
lines = lines.reverse if order == :bottom
|
1295
|
+
lines.map{ |l| l + "\n" }.join
|
1296
|
+
}
|
1297
|
+
# The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object.
|
1298
|
+
message = message.gsub(/\(irb\):(?<num>\d+):in (?<open_quote>[`'])<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}<main>'" }
|
1299
|
+
puts message
|
1300
|
+
puts 'Maybe IRB bug!' if irb_bug
|
1301
|
+
rescue Exception => handler_exc
|
1302
|
+
begin
|
1303
|
+
puts exc.inspect
|
1304
|
+
puts "backtraces are hidden because #{handler_exc} was raised when processing them"
|
1305
|
+
rescue Exception
|
1306
|
+
puts 'Uninspectable exception occurred'
|
1307
|
+
end
|
678
1308
|
end
|
679
1309
|
|
680
|
-
# Evaluates the given block using the given
|
681
|
-
#
|
1310
|
+
# Evaluates the given block using the given `path` as the Context#irb_path and
|
1311
|
+
# `name` as the Context#irb_name.
|
682
1312
|
#
|
683
|
-
# Used by the irb command
|
684
|
-
# information.
|
1313
|
+
# Used by the irb command `source`, see IRB@IRB+Sessions for more information.
|
685
1314
|
def suspend_name(path = nil, name = nil)
|
686
1315
|
@context.irb_path, back_path = path, @context.irb_path if path
|
687
1316
|
@context.irb_name, back_name = name, @context.irb_name if name
|
@@ -693,25 +1322,22 @@ module IRB
|
|
693
1322
|
end
|
694
1323
|
end
|
695
1324
|
|
696
|
-
# Evaluates the given block using the given
|
1325
|
+
# Evaluates the given block using the given `workspace` as the
|
697
1326
|
# Context#workspace.
|
698
1327
|
#
|
699
|
-
# Used by the irb command
|
700
|
-
# information.
|
1328
|
+
# Used by the irb command `irb_load`, see IRB@IRB+Sessions for more information.
|
701
1329
|
def suspend_workspace(workspace)
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
end
|
1330
|
+
current_workspace = @context.workspace
|
1331
|
+
@context.replace_workspace(workspace)
|
1332
|
+
yield
|
1333
|
+
ensure
|
1334
|
+
@context.replace_workspace current_workspace
|
708
1335
|
end
|
709
1336
|
|
710
|
-
# Evaluates the given block using the given
|
711
|
-
# Context#io.
|
1337
|
+
# Evaluates the given block using the given `input_method` as the Context#io.
|
712
1338
|
#
|
713
|
-
# Used by the irb commands
|
714
|
-
#
|
1339
|
+
# Used by the irb commands `source` and `irb_load`, see IRB@IRB+Sessions for
|
1340
|
+
# more information.
|
715
1341
|
def suspend_input_method(input_method)
|
716
1342
|
back_io = @context.io
|
717
1343
|
@context.instance_eval{@io = input_method}
|
@@ -722,16 +1348,6 @@ module IRB
|
|
722
1348
|
end
|
723
1349
|
end
|
724
1350
|
|
725
|
-
# Evaluates the given block using the given +context+ as the Context.
|
726
|
-
def suspend_context(context)
|
727
|
-
@context, back_context = context, @context
|
728
|
-
begin
|
729
|
-
yield back_context
|
730
|
-
ensure
|
731
|
-
@context = back_context
|
732
|
-
end
|
733
|
-
end
|
734
|
-
|
735
1351
|
# Handler for the signal SIGINT, see Kernel#trap for more information.
|
736
1352
|
def signal_handle
|
737
1353
|
unless @context.ignore_sigint?
|
@@ -754,7 +1370,7 @@ module IRB
|
|
754
1370
|
end
|
755
1371
|
end
|
756
1372
|
|
757
|
-
# Evaluates the given block using the given
|
1373
|
+
# Evaluates the given block using the given `status`.
|
758
1374
|
def signal_status(status)
|
759
1375
|
return yield if @signal_status == :IN_LOAD
|
760
1376
|
|
@@ -767,54 +1383,6 @@ module IRB
|
|
767
1383
|
end
|
768
1384
|
end
|
769
1385
|
|
770
|
-
def truncate_prompt_main(str) # :nodoc:
|
771
|
-
str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
|
772
|
-
if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
|
773
|
-
str
|
774
|
-
else
|
775
|
-
str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
|
776
|
-
end
|
777
|
-
end
|
778
|
-
|
779
|
-
def prompt(prompt, ltype, indent, line_no) # :nodoc:
|
780
|
-
p = prompt.dup
|
781
|
-
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
782
|
-
case $2
|
783
|
-
when "N"
|
784
|
-
@context.irb_name
|
785
|
-
when "m"
|
786
|
-
truncate_prompt_main(@context.main.to_s)
|
787
|
-
when "M"
|
788
|
-
truncate_prompt_main(@context.main.inspect)
|
789
|
-
when "l"
|
790
|
-
ltype
|
791
|
-
when "i"
|
792
|
-
if indent < 0
|
793
|
-
if $1
|
794
|
-
"-".rjust($1.to_i)
|
795
|
-
else
|
796
|
-
"-"
|
797
|
-
end
|
798
|
-
else
|
799
|
-
if $1
|
800
|
-
format("%" + $1 + "d", indent)
|
801
|
-
else
|
802
|
-
indent.to_s
|
803
|
-
end
|
804
|
-
end
|
805
|
-
when "n"
|
806
|
-
if $1
|
807
|
-
format("%" + $1 + "d", line_no)
|
808
|
-
else
|
809
|
-
line_no.to_s
|
810
|
-
end
|
811
|
-
when "%"
|
812
|
-
"%"
|
813
|
-
end
|
814
|
-
end
|
815
|
-
p
|
816
|
-
end
|
817
|
-
|
818
1386
|
def output_value(omit = false) # :nodoc:
|
819
1387
|
str = @context.inspect_last_value
|
820
1388
|
multiline_p = str.include?("\n")
|
@@ -844,15 +1412,16 @@ module IRB
|
|
844
1412
|
end
|
845
1413
|
end
|
846
1414
|
end
|
1415
|
+
|
847
1416
|
if multiline_p && @context.newline_before_multiline_output?
|
848
|
-
|
849
|
-
else
|
850
|
-
printf @context.return_format, str
|
1417
|
+
str = "\n" + str
|
851
1418
|
end
|
1419
|
+
|
1420
|
+
Pager.page_content(format(@context.return_format, str), retain_content: true)
|
852
1421
|
end
|
853
1422
|
|
854
|
-
# Outputs the local variables to this current session, including
|
855
|
-
#
|
1423
|
+
# Outputs the local variables to this current session, including #signal_status
|
1424
|
+
# and #context, using IRB::Locale.
|
856
1425
|
def inspect
|
857
1426
|
ary = []
|
858
1427
|
for iv in instance_variables
|
@@ -868,55 +1437,94 @@ module IRB
|
|
868
1437
|
format("#<%s: %s>", self.class, ary.join(", "))
|
869
1438
|
end
|
870
1439
|
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
1440
|
+
private
|
1441
|
+
|
1442
|
+
def generate_prompt(opens, continue, line_offset)
|
1443
|
+
ltype = @scanner.ltype_from_open_tokens(opens)
|
1444
|
+
indent = @scanner.calc_indent_level(opens)
|
1445
|
+
continue = opens.any? || continue
|
1446
|
+
line_no = @line_no + line_offset
|
1447
|
+
|
1448
|
+
if ltype
|
1449
|
+
f = @context.prompt_s
|
1450
|
+
elsif continue
|
1451
|
+
f = @context.prompt_c
|
1452
|
+
else
|
1453
|
+
f = @context.prompt_i
|
1454
|
+
end
|
1455
|
+
f = "" unless f
|
1456
|
+
if @context.prompting?
|
1457
|
+
p = format_prompt(f, ltype, indent, line_no)
|
1458
|
+
else
|
1459
|
+
p = ""
|
1460
|
+
end
|
1461
|
+
if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent)
|
1462
|
+
unless ltype
|
1463
|
+
prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i
|
1464
|
+
ind = format_prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
1465
|
+
indent * 2 - p.size
|
1466
|
+
p += " " * ind if ind > 0
|
1467
|
+
end
|
1468
|
+
end
|
1469
|
+
p
|
887
1470
|
end
|
888
|
-
end
|
889
1471
|
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
895
|
-
case k
|
896
|
-
when :MAIN_CONTEXT, :__TMP__EHV__
|
897
|
-
array.push format("CONF[:%s]=...myself...", k.id2name)
|
898
|
-
when :PROMPT
|
899
|
-
s = v.collect{
|
900
|
-
|kk, vv|
|
901
|
-
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
902
|
-
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
903
|
-
}
|
904
|
-
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
1472
|
+
def truncate_prompt_main(str) # :nodoc:
|
1473
|
+
str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ')
|
1474
|
+
if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH
|
1475
|
+
str
|
905
1476
|
else
|
906
|
-
|
1477
|
+
str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION
|
1478
|
+
end
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
def format_prompt(format, ltype, indent, line_no) # :nodoc:
|
1482
|
+
format.gsub(/%([0-9]+)?([a-zA-Z%])/) do
|
1483
|
+
case $2
|
1484
|
+
when "N"
|
1485
|
+
@context.irb_name
|
1486
|
+
when "m"
|
1487
|
+
main_str = @context.main.to_s rescue "!#{$!.class}"
|
1488
|
+
truncate_prompt_main(main_str)
|
1489
|
+
when "M"
|
1490
|
+
main_str = @context.main.inspect rescue "!#{$!.class}"
|
1491
|
+
truncate_prompt_main(main_str)
|
1492
|
+
when "l"
|
1493
|
+
ltype
|
1494
|
+
when "i"
|
1495
|
+
if indent < 0
|
1496
|
+
if $1
|
1497
|
+
"-".rjust($1.to_i)
|
1498
|
+
else
|
1499
|
+
"-"
|
1500
|
+
end
|
1501
|
+
else
|
1502
|
+
if $1
|
1503
|
+
format("%" + $1 + "d", indent)
|
1504
|
+
else
|
1505
|
+
indent.to_s
|
1506
|
+
end
|
1507
|
+
end
|
1508
|
+
when "n"
|
1509
|
+
if $1
|
1510
|
+
format("%" + $1 + "d", line_no)
|
1511
|
+
else
|
1512
|
+
line_no.to_s
|
1513
|
+
end
|
1514
|
+
when "%"
|
1515
|
+
"%" unless $1
|
1516
|
+
end
|
907
1517
|
end
|
908
1518
|
end
|
909
|
-
array.join("\n")
|
910
1519
|
end
|
911
1520
|
end
|
912
1521
|
|
913
1522
|
class Binding
|
914
|
-
# Opens an IRB session where
|
915
|
-
# interactive debugging. You can call any methods or variables available in
|
916
|
-
#
|
917
|
-
#
|
1523
|
+
# Opens an IRB session where `binding.irb` is called which allows for
|
1524
|
+
# interactive debugging. You can call any methods or variables available in the
|
1525
|
+
# current scope, and mutate state if you need to.
|
918
1526
|
#
|
919
|
-
# Given a Ruby file called
|
1527
|
+
# Given a Ruby file called `potato.rb` containing the following code:
|
920
1528
|
#
|
921
1529
|
# class Potato
|
922
1530
|
# def initialize
|
@@ -928,8 +1536,8 @@ class Binding
|
|
928
1536
|
#
|
929
1537
|
# Potato.new
|
930
1538
|
#
|
931
|
-
# Running
|
932
|
-
#
|
1539
|
+
# Running `ruby potato.rb` will open an IRB session where `binding.irb` is
|
1540
|
+
# called, and you will see the following:
|
933
1541
|
#
|
934
1542
|
# $ ruby potato.rb
|
935
1543
|
#
|
@@ -959,22 +1567,42 @@ class Binding
|
|
959
1567
|
# irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
|
960
1568
|
# => true
|
961
1569
|
#
|
962
|
-
# You can exit the IRB session with the
|
963
|
-
# resume execution where
|
1570
|
+
# You can exit the IRB session with the `exit` command. Note that exiting will
|
1571
|
+
# resume execution where `binding.irb` had paused it, as you can see from the
|
964
1572
|
# output printed to standard output in this example:
|
965
1573
|
#
|
966
1574
|
# irb(#<Potato:0x00007feea1916670>):005:0> exit
|
967
1575
|
# Cooked potato: true
|
968
1576
|
#
|
969
|
-
#
|
970
|
-
# See IRB@IRB+Usage for more information.
|
1577
|
+
# See IRB for more information.
|
971
1578
|
def irb(show_code: true)
|
972
|
-
IRB
|
1579
|
+
# Setup IRB with the current file's path and no command line arguments
|
1580
|
+
IRB.setup(source_location[0], argv: []) unless IRB.initialized?
|
1581
|
+
# Create a new workspace using the current binding
|
973
1582
|
workspace = IRB::WorkSpace.new(self)
|
1583
|
+
# Print the code around the binding if show_code is true
|
974
1584
|
STDOUT.print(workspace.code_around_binding) if show_code
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
1585
|
+
# Get the original IRB instance
|
1586
|
+
debugger_irb = IRB.instance_variable_get(:@debugger_irb)
|
1587
|
+
|
1588
|
+
irb_path = File.expand_path(source_location[0])
|
1589
|
+
|
1590
|
+
if debugger_irb
|
1591
|
+
# If we're already in a debugger session, set the workspace and irb_path for the original IRB instance
|
1592
|
+
debugger_irb.context.replace_workspace(workspace)
|
1593
|
+
debugger_irb.context.irb_path = irb_path
|
1594
|
+
# If we've started a debugger session and hit another binding.irb, we don't want
|
1595
|
+
# to start an IRB session instead, we want to resume the irb:rdbg session.
|
1596
|
+
IRB::Debug.setup(debugger_irb)
|
1597
|
+
IRB::Debug.insert_debug_break
|
1598
|
+
debugger_irb.debug_break
|
1599
|
+
else
|
1600
|
+
# If we're not in a debugger session, create a new IRB instance with the current
|
1601
|
+
# workspace
|
1602
|
+
binding_irb = IRB::Irb.new(workspace, from_binding: true)
|
1603
|
+
binding_irb.context.irb_path = irb_path
|
1604
|
+
binding_irb.run(IRB.conf)
|
1605
|
+
binding_irb.debug_break
|
1606
|
+
end
|
979
1607
|
end
|
980
1608
|
end
|