irb 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +10 -0
- data/bin/console +6 -0
- data/bin/setup +6 -0
- data/exe/irb +11 -0
- data/irb.gemspec +26 -0
- data/lib/irb.rb +798 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +42 -0
- data/lib/irb/cmd/load.rb +67 -0
- data/lib/irb/cmd/nop.rb +39 -0
- data/lib/irb/cmd/pushws.rb +41 -0
- data/lib/irb/cmd/subirb.rb +43 -0
- data/lib/irb/completion.rb +244 -0
- data/lib/irb/context.rb +425 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +119 -0
- data/lib/irb/ext/loader.rb +129 -0
- data/lib/irb/ext/multi-irb.rb +265 -0
- data/lib/irb/ext/save-history.rb +105 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +74 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +306 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +302 -0
- data/lib/irb/input-method.rb +192 -0
- data/lib/irb/inspector.rb +132 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +49 -0
- data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
- data/lib/irb/lc/ja/error.rb +31 -0
- data/lib/irb/lc/ja/help-message +52 -0
- data/lib/irb/locale.rb +182 -0
- data/lib/irb/magic-file.rb +38 -0
- data/lib/irb/notifier.rb +232 -0
- data/lib/irb/output-method.rb +92 -0
- data/lib/irb/ruby-lex.rb +1180 -0
- data/lib/irb/ruby-token.rb +267 -0
- data/lib/irb/slex.rb +282 -0
- data/lib/irb/src_encoding.rb +7 -0
- data/lib/irb/version.rb +17 -0
- data/lib/irb/workspace.rb +143 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 423daf218fc081796e0be9093dea7df2340782475a57d97cc279f55482d5ba09
|
4
|
+
data.tar.gz: c2990b036ee5b6f1cab514e11be623d67eed699729e361bea46b2722bd0eea8b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 190785277de97de1faef3c9aa599ad15c456c20da76eed4559a8e32f4c49aaf957884b083677ce5fc31c9974353f3f3dbc4a4a3aef29f36a703b16929656600d
|
7
|
+
data.tar.gz: b79eb0f94a33aa34afc6ebf7124e9e72ae4cad283063d369ab7ca7e3b86adb88248d1fc3e0dd3df7f6584c6222e93baf09a0d776a686772ab99508b5d5706b05
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# IRB
|
2
|
+
|
3
|
+
IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions read from the standard input.
|
4
|
+
|
5
|
+
The `irb` command from your shell will start the interpreter.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'irb'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install irb
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Use of irb is easy if you know Ruby.
|
26
|
+
|
27
|
+
When executing irb, prompts are displayed as follows. Then, enter the Ruby expression. An input is executed when it is syntactically complete.
|
28
|
+
|
29
|
+
```
|
30
|
+
$ irb
|
31
|
+
irb(main):001:0> 1+2
|
32
|
+
#=> 3
|
33
|
+
irb(main):002:0> class Foo
|
34
|
+
irb(main):003:1> def foo
|
35
|
+
irb(main):004:2> print 1
|
36
|
+
irb(main):005:2> end
|
37
|
+
irb(main):006:1> end
|
38
|
+
#=> nil
|
39
|
+
```
|
40
|
+
|
41
|
+
The Readline extension module can be used with irb. Use of Readline is default if it's installed.
|
42
|
+
|
43
|
+
## Development
|
44
|
+
|
45
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
46
|
+
|
47
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
48
|
+
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/irb.
|
52
|
+
|
53
|
+
## License
|
54
|
+
|
55
|
+
The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/exe/irb
ADDED
data/irb.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require_relative "lib/irb/version"
|
3
|
+
rescue LoadError
|
4
|
+
# for Ruby core repository
|
5
|
+
require_relative "version"
|
6
|
+
end
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "irb"
|
10
|
+
spec.version = IRB::VERSION
|
11
|
+
spec.authors = ["Keiju ISHITSUKA"]
|
12
|
+
spec.email = ["keiju@ruby-lang.org"]
|
13
|
+
|
14
|
+
spec.summary = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
|
15
|
+
spec.description = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).}
|
16
|
+
spec.homepage = "https://github.com/ruby/irb"
|
17
|
+
spec.license = "BSD-2-Clause"
|
18
|
+
|
19
|
+
spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "exe/irb", "irb.gemspec", "lib/irb.rb", "lib/irb/cmd/chws.rb", "lib/irb/cmd/fork.rb", "lib/irb/cmd/help.rb", "lib/irb/cmd/load.rb", "lib/irb/cmd/nop.rb", "lib/irb/cmd/pushws.rb", "lib/irb/cmd/subirb.rb", "lib/irb/completion.rb", "lib/irb/context.rb", "lib/irb/ext/change-ws.rb", "lib/irb/ext/history.rb", "lib/irb/ext/loader.rb", "lib/irb/ext/multi-irb.rb", "lib/irb/ext/save-history.rb", "lib/irb/ext/tracer.rb", "lib/irb/ext/use-loader.rb", "lib/irb/ext/workspaces.rb", "lib/irb/extend-command.rb", "lib/irb/frame.rb", "lib/irb/help.rb", "lib/irb/init.rb", "lib/irb/input-method.rb", "lib/irb/inspector.rb", "lib/irb/lc/.document", "lib/irb/lc/error.rb", "lib/irb/lc/help-message", "lib/irb/lc/ja/encoding_aliases.rb", "lib/irb/lc/ja/error.rb", "lib/irb/lc/ja/help-message", "lib/irb/locale.rb", "lib/irb/magic-file.rb", "lib/irb/notifier.rb", "lib/irb/output-method.rb", "lib/irb/ruby-lex.rb", "lib/irb/ruby-token.rb", "lib/irb/slex.rb", "lib/irb/src_encoding.rb", "lib/irb/version.rb", "lib/irb/workspace.rb", "lib/irb/ws-for-case-2.rb", "lib/irb/xmp.rb"]
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
data/lib/irb.rb
ADDED
@@ -0,0 +1,798 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb.rb - irb main module
|
4
|
+
# $Release Version: 0.9.6 $
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
require "e2mmap"
|
13
|
+
|
14
|
+
require "irb/init"
|
15
|
+
require "irb/context"
|
16
|
+
require "irb/extend-command"
|
17
|
+
|
18
|
+
require "irb/ruby-lex"
|
19
|
+
require "irb/input-method"
|
20
|
+
require "irb/locale"
|
21
|
+
|
22
|
+
require "irb/version"
|
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
|
+
# -d Set $DEBUG to true (same as `ruby -d')
|
54
|
+
# -r load-module Same as `ruby -r'
|
55
|
+
# -I path Specify $LOAD_PATH directory
|
56
|
+
# -U Same as `ruby -U`
|
57
|
+
# -E enc Same as `ruby -E`
|
58
|
+
# -w Same as `ruby -w`
|
59
|
+
# -W[level=2] Same as `ruby -W`
|
60
|
+
# --inspect Use `inspect' for output (default except for bc mode)
|
61
|
+
# --noinspect Don't use inspect for output
|
62
|
+
# --readline Use Readline extension module
|
63
|
+
# --noreadline Don't use Readline extension module
|
64
|
+
# --prompt prompt-mode
|
65
|
+
# --prompt-mode prompt-mode
|
66
|
+
# Switch prompt mode. Pre-defined prompt modes are
|
67
|
+
# `default', `simple', `xmp' and `inf-ruby'
|
68
|
+
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
69
|
+
# Suppresses --readline.
|
70
|
+
# --simple-prompt Simple prompt mode
|
71
|
+
# --noprompt No prompt mode
|
72
|
+
# --tracer Display trace for each execution of commands.
|
73
|
+
# --back-trace-limit n
|
74
|
+
# Display backtrace top n and tail n. The default
|
75
|
+
# value is 16.
|
76
|
+
# --irb_debug n Set internal debug level to n (not for popular use)
|
77
|
+
# -v, --version Print the version of irb
|
78
|
+
#
|
79
|
+
# == Configuration
|
80
|
+
#
|
81
|
+
# IRB reads from <code>~/.irbrc</code> when it's invoked.
|
82
|
+
#
|
83
|
+
# If <code>~/.irbrc</code> doesn't exist, +irb+ will try to read in the following order:
|
84
|
+
#
|
85
|
+
# * +.irbrc+
|
86
|
+
# * +irb.rc+
|
87
|
+
# * +_irbrc+
|
88
|
+
# * <code>$irbrc</code>
|
89
|
+
#
|
90
|
+
# The following are alternatives to the command line options. To use them type
|
91
|
+
# as follows in an +irb+ session:
|
92
|
+
#
|
93
|
+
# IRB.conf[:IRB_NAME]="irb"
|
94
|
+
# IRB.conf[:INSPECT_MODE]=nil
|
95
|
+
# IRB.conf[:IRB_RC] = nil
|
96
|
+
# IRB.conf[:BACK_TRACE_LIMIT]=16
|
97
|
+
# IRB.conf[:USE_LOADER] = false
|
98
|
+
# IRB.conf[:USE_READLINE] = nil
|
99
|
+
# IRB.conf[:USE_TRACER] = false
|
100
|
+
# IRB.conf[:IGNORE_SIGINT] = true
|
101
|
+
# IRB.conf[:IGNORE_EOF] = false
|
102
|
+
# IRB.conf[:PROMPT_MODE] = :DEFAULT
|
103
|
+
# IRB.conf[:PROMPT] = {...}
|
104
|
+
# IRB.conf[:DEBUG_LEVEL]=0
|
105
|
+
#
|
106
|
+
# === Auto indentation
|
107
|
+
#
|
108
|
+
# To enable auto-indent mode in irb, add the following to your +.irbrc+:
|
109
|
+
#
|
110
|
+
# IRB.conf[:AUTO_INDENT] = true
|
111
|
+
#
|
112
|
+
# === Autocompletion
|
113
|
+
#
|
114
|
+
# To enable autocompletion for irb, add the following to your +.irbrc+:
|
115
|
+
#
|
116
|
+
# require 'irb/completion'
|
117
|
+
#
|
118
|
+
# === History
|
119
|
+
#
|
120
|
+
# By default, irb disables history and will not store any commands you used.
|
121
|
+
#
|
122
|
+
# If you want to enable history, add the following to your +.irbrc+:
|
123
|
+
#
|
124
|
+
# IRB.conf[:SAVE_HISTORY] = 1000
|
125
|
+
#
|
126
|
+
# This will now store the last 1000 commands in <code>~/.irb_history</code>.
|
127
|
+
#
|
128
|
+
# See IRB::Context#save_history= for more information.
|
129
|
+
#
|
130
|
+
# == Customizing the IRB Prompt
|
131
|
+
#
|
132
|
+
# In order to customize the prompt, you can change the following Hash:
|
133
|
+
#
|
134
|
+
# IRB.conf[:PROMPT]
|
135
|
+
#
|
136
|
+
# This example can be used in your +.irbrc+
|
137
|
+
#
|
138
|
+
# IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
|
139
|
+
# :AUTO_INDENT => true, # enables auto-indent mode
|
140
|
+
# :PROMPT_I => ">> ", # simple prompt
|
141
|
+
# :PROMPT_S => nil, # prompt for continuated strings
|
142
|
+
# :PROMPT_C => nil, # prompt for continuated statement
|
143
|
+
# :RETURN => " ==>%s\n" # format to return value
|
144
|
+
# }
|
145
|
+
#
|
146
|
+
# IRB.conf[:PROMPT_MODE] = :MY_PROMPT
|
147
|
+
#
|
148
|
+
# Or, invoke irb with the above prompt mode by:
|
149
|
+
#
|
150
|
+
# irb --prompt my-prompt
|
151
|
+
#
|
152
|
+
# Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
|
153
|
+
# prompt specification, some special strings are available:
|
154
|
+
#
|
155
|
+
# %N # command name which is running
|
156
|
+
# %m # to_s of main object (self)
|
157
|
+
# %M # inspect of main object (self)
|
158
|
+
# %l # type of string(", ', /, ]), `]' is inner %w[...]
|
159
|
+
# %NNi # indent level. NN is digits and means as same as printf("%NNd").
|
160
|
+
# # It can be omitted
|
161
|
+
# %NNn # line number.
|
162
|
+
# %% # %
|
163
|
+
#
|
164
|
+
# For instance, the default prompt mode is defined as follows:
|
165
|
+
#
|
166
|
+
# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
|
167
|
+
# :PROMPT_I => "%N(%m):%03n:%i> ",
|
168
|
+
# :PROMPT_S => "%N(%m):%03n:%i%l ",
|
169
|
+
# :PROMPT_C => "%N(%m):%03n:%i* ",
|
170
|
+
# :RETURN => "%s\n" # used to printf
|
171
|
+
# }
|
172
|
+
#
|
173
|
+
# irb comes with a number of available modes:
|
174
|
+
#
|
175
|
+
# # :NULL:
|
176
|
+
# # :PROMPT_I:
|
177
|
+
# # :PROMPT_N:
|
178
|
+
# # :PROMPT_S:
|
179
|
+
# # :PROMPT_C:
|
180
|
+
# # :RETURN: |
|
181
|
+
# # %s
|
182
|
+
# # :DEFAULT:
|
183
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
184
|
+
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
185
|
+
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
186
|
+
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
187
|
+
# # :RETURN: |
|
188
|
+
# # => %s
|
189
|
+
# # :CLASSIC:
|
190
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
191
|
+
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
|
192
|
+
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
|
193
|
+
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
|
194
|
+
# # :RETURN: |
|
195
|
+
# # %s
|
196
|
+
# # :SIMPLE:
|
197
|
+
# # :PROMPT_I: ! '>> '
|
198
|
+
# # :PROMPT_N: ! '>> '
|
199
|
+
# # :PROMPT_S:
|
200
|
+
# # :PROMPT_C: ! '?> '
|
201
|
+
# # :RETURN: |
|
202
|
+
# # => %s
|
203
|
+
# # :INF_RUBY:
|
204
|
+
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
|
205
|
+
# # :PROMPT_N:
|
206
|
+
# # :PROMPT_S:
|
207
|
+
# # :PROMPT_C:
|
208
|
+
# # :RETURN: |
|
209
|
+
# # %s
|
210
|
+
# # :AUTO_INDENT: true
|
211
|
+
# # :XMP:
|
212
|
+
# # :PROMPT_I:
|
213
|
+
# # :PROMPT_N:
|
214
|
+
# # :PROMPT_S:
|
215
|
+
# # :PROMPT_C:
|
216
|
+
# # :RETURN: |2
|
217
|
+
# # ==>%s
|
218
|
+
#
|
219
|
+
# == Restrictions
|
220
|
+
#
|
221
|
+
# Because irb evaluates input immediately after it is syntactically complete,
|
222
|
+
# the results may be slightly different than directly using Ruby.
|
223
|
+
#
|
224
|
+
# == IRB Sessions
|
225
|
+
#
|
226
|
+
# IRB has a special feature, that allows you to manage many sessions at once.
|
227
|
+
#
|
228
|
+
# You can create new sessions with Irb.irb, and get a list of current sessions
|
229
|
+
# with the +jobs+ command in the prompt.
|
230
|
+
#
|
231
|
+
# === Commands
|
232
|
+
#
|
233
|
+
# JobManager provides commands to handle the current sessions:
|
234
|
+
#
|
235
|
+
# jobs # List of current sessions
|
236
|
+
# fg # Switches to the session of the given number
|
237
|
+
# kill # Kills the session with the given number
|
238
|
+
#
|
239
|
+
# The +exit+ command, or ::irb_exit, will quit the current session and call any
|
240
|
+
# exit hooks with IRB.irb_at_exit.
|
241
|
+
#
|
242
|
+
# A few commands for loading files within the session are also available:
|
243
|
+
#
|
244
|
+
# +source+::
|
245
|
+
# Loads a given file in the current session and displays the source lines,
|
246
|
+
# see IrbLoader#source_file
|
247
|
+
# +irb_load+::
|
248
|
+
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
|
249
|
+
# +irb_require+::
|
250
|
+
# Loads the given file similarly to Kernel#require
|
251
|
+
#
|
252
|
+
# === Configuration
|
253
|
+
#
|
254
|
+
# The command line options, or IRB.conf, specify the default behavior of
|
255
|
+
# Irb.irb.
|
256
|
+
#
|
257
|
+
# On the other hand, each conf in IRB@Command+line+options is used to
|
258
|
+
# individually configure IRB.irb.
|
259
|
+
#
|
260
|
+
# If a proc is set for IRB.conf[:IRB_RC], its will be invoked after execution
|
261
|
+
# of that proc with the context of the current session as its argument. Each
|
262
|
+
# session can be configured using this mechanism.
|
263
|
+
#
|
264
|
+
# === Session variables
|
265
|
+
#
|
266
|
+
# There are a few variables in every Irb session that can come in handy:
|
267
|
+
#
|
268
|
+
# <code>_</code>::
|
269
|
+
# The value command executed, as a local variable
|
270
|
+
# <code>__</code>::
|
271
|
+
# The history of evaluated commands
|
272
|
+
# <code>__[line_no]</code>::
|
273
|
+
# Returns the evaluation value at the given line number, +line_no+.
|
274
|
+
# If +line_no+ is a negative, the return value +line_no+ many lines before
|
275
|
+
# the most recent return value.
|
276
|
+
#
|
277
|
+
# === Example using IRB Sessions
|
278
|
+
#
|
279
|
+
# # invoke a new session
|
280
|
+
# irb(main):001:0> irb
|
281
|
+
# # list open sessions
|
282
|
+
# irb.1(main):001:0> jobs
|
283
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
|
284
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : running)
|
285
|
+
#
|
286
|
+
# # change the active session
|
287
|
+
# irb.1(main):002:0> fg 0
|
288
|
+
# # define class Foo in top-level session
|
289
|
+
# irb(main):002:0> class Foo;end
|
290
|
+
# # invoke a new session with the context of Foo
|
291
|
+
# irb(main):003:0> irb Foo
|
292
|
+
# # define Foo#foo
|
293
|
+
# irb.2(Foo):001:0> def foo
|
294
|
+
# irb.2(Foo):002:1> print 1
|
295
|
+
# irb.2(Foo):003:1> end
|
296
|
+
#
|
297
|
+
# # change the active session
|
298
|
+
# irb.2(Foo):004:0> fg 0
|
299
|
+
# # list open sessions
|
300
|
+
# irb(main):004:0> jobs
|
301
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
302
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
303
|
+
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
304
|
+
# # check if Foo#foo is available
|
305
|
+
# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
|
306
|
+
#
|
307
|
+
# # change the active sesssion
|
308
|
+
# irb(main):006:0> fg 2
|
309
|
+
# # define Foo#bar in the context of Foo
|
310
|
+
# irb.2(Foo):005:0> def bar
|
311
|
+
# irb.2(Foo):006:1> print "bar"
|
312
|
+
# irb.2(Foo):007:1> end
|
313
|
+
# irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
|
314
|
+
#
|
315
|
+
# # change the active session
|
316
|
+
# irb.2(Foo):011:0> fg 0
|
317
|
+
# irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
|
318
|
+
# # invoke a new session with the context of f (instance of Foo)
|
319
|
+
# irb(main):008:0> irb f
|
320
|
+
# # list open sessions
|
321
|
+
# irb.3(<Foo:0x4010af3c>):001:0> jobs
|
322
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
|
323
|
+
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
|
324
|
+
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
|
325
|
+
# #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
|
326
|
+
# # evaluate f.foo
|
327
|
+
# irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
|
328
|
+
# # evaluate f.bar
|
329
|
+
# irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
|
330
|
+
# # kill jobs 1, 2, and 3
|
331
|
+
# irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
|
332
|
+
# # list open sessions, should only include main session
|
333
|
+
# irb(main):009:0> jobs
|
334
|
+
# #0->irb on main (#<Thread:0x400fb7e4> : running)
|
335
|
+
# # quit irb
|
336
|
+
# irb(main):010:0> exit
|
337
|
+
module IRB
|
338
|
+
|
339
|
+
# An exception raised by IRB.irb_abort
|
340
|
+
class Abort < Exception;end
|
341
|
+
|
342
|
+
@CONF = {}
|
343
|
+
|
344
|
+
|
345
|
+
# Displays current configuration.
|
346
|
+
#
|
347
|
+
# Modifying the configuration is achieved by sending a message to IRB.conf.
|
348
|
+
#
|
349
|
+
# See IRB@Configuration for more information.
|
350
|
+
def IRB.conf
|
351
|
+
@CONF
|
352
|
+
end
|
353
|
+
|
354
|
+
# Returns the current version of IRB, including release version and last
|
355
|
+
# updated date.
|
356
|
+
def IRB.version
|
357
|
+
if v = @CONF[:VERSION] then return v end
|
358
|
+
|
359
|
+
@CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
|
360
|
+
end
|
361
|
+
|
362
|
+
# The current IRB::Context of the session, see IRB.conf
|
363
|
+
#
|
364
|
+
# irb
|
365
|
+
# irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
|
366
|
+
# foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
|
367
|
+
def IRB.CurrentContext
|
368
|
+
IRB.conf[:MAIN_CONTEXT]
|
369
|
+
end
|
370
|
+
|
371
|
+
# Initializes IRB and creates a new Irb.irb object at the +TOPLEVEL_BINDING+
|
372
|
+
def IRB.start(ap_path = nil)
|
373
|
+
STDOUT.sync = true
|
374
|
+
$0 = File::basename(ap_path, ".rb") if ap_path
|
375
|
+
|
376
|
+
IRB.setup(ap_path)
|
377
|
+
|
378
|
+
if @CONF[:SCRIPT]
|
379
|
+
irb = Irb.new(nil, @CONF[:SCRIPT])
|
380
|
+
else
|
381
|
+
irb = Irb.new
|
382
|
+
end
|
383
|
+
irb.run(@CONF)
|
384
|
+
end
|
385
|
+
|
386
|
+
# Calls each event hook of IRB.conf[:AT_EXIT] when the current session quits.
|
387
|
+
def IRB.irb_at_exit
|
388
|
+
@CONF[:AT_EXIT].each{|hook| hook.call}
|
389
|
+
end
|
390
|
+
|
391
|
+
# Quits irb
|
392
|
+
def IRB.irb_exit(irb, ret)
|
393
|
+
throw :IRB_EXIT, ret
|
394
|
+
end
|
395
|
+
|
396
|
+
# Aborts then interrupts irb.
|
397
|
+
#
|
398
|
+
# Will raise an Abort exception, or the given +exception+.
|
399
|
+
def IRB.irb_abort(irb, exception = Abort)
|
400
|
+
if defined? Thread
|
401
|
+
irb.context.thread.raise exception, "abort then interrupt!"
|
402
|
+
else
|
403
|
+
raise exception, "abort then interrupt!"
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
class Irb
|
408
|
+
# Creates a new irb session
|
409
|
+
def initialize(workspace = nil, input_method = nil, output_method = nil)
|
410
|
+
@context = Context.new(self, workspace, input_method, output_method)
|
411
|
+
@context.main.extend ExtendCommandBundle
|
412
|
+
@signal_status = :IN_IRB
|
413
|
+
|
414
|
+
@scanner = RubyLex.new
|
415
|
+
@scanner.exception_on_syntax_error = false
|
416
|
+
end
|
417
|
+
|
418
|
+
def run(conf = IRB.conf)
|
419
|
+
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
420
|
+
conf[:MAIN_CONTEXT] = context
|
421
|
+
|
422
|
+
trap("SIGINT") do
|
423
|
+
signal_handle
|
424
|
+
end
|
425
|
+
|
426
|
+
begin
|
427
|
+
catch(:IRB_EXIT) do
|
428
|
+
eval_input
|
429
|
+
end
|
430
|
+
ensure
|
431
|
+
conf[:AT_EXIT].each{|hook| hook.call}
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
# Returns the current context of this irb session
|
436
|
+
attr_reader :context
|
437
|
+
# The lexer used by this irb session
|
438
|
+
attr_accessor :scanner
|
439
|
+
|
440
|
+
# Evaluates input for this session.
|
441
|
+
def eval_input
|
442
|
+
exc = nil
|
443
|
+
|
444
|
+
@scanner.set_prompt do
|
445
|
+
|ltype, indent, continue, line_no|
|
446
|
+
if ltype
|
447
|
+
f = @context.prompt_s
|
448
|
+
elsif continue
|
449
|
+
f = @context.prompt_c
|
450
|
+
elsif indent > 0
|
451
|
+
f = @context.prompt_n
|
452
|
+
else
|
453
|
+
f = @context.prompt_i
|
454
|
+
end
|
455
|
+
f = "" unless f
|
456
|
+
if @context.prompting?
|
457
|
+
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
458
|
+
else
|
459
|
+
@context.io.prompt = p = ""
|
460
|
+
end
|
461
|
+
if @context.auto_indent_mode
|
462
|
+
unless ltype
|
463
|
+
ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
|
464
|
+
indent * 2 - p.size
|
465
|
+
ind += 2 if continue
|
466
|
+
@context.io.prompt = p + " " * ind if ind > 0
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
@scanner.set_input(@context.io) do
|
472
|
+
signal_status(:IN_INPUT) do
|
473
|
+
if l = @context.io.gets
|
474
|
+
print l if @context.verbose?
|
475
|
+
else
|
476
|
+
if @context.ignore_eof? and @context.io.readable_after_eof?
|
477
|
+
l = "\n"
|
478
|
+
if @context.verbose?
|
479
|
+
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
480
|
+
end
|
481
|
+
else
|
482
|
+
print "\n"
|
483
|
+
end
|
484
|
+
end
|
485
|
+
l
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
@scanner.each_top_level_statement do |line, line_no|
|
490
|
+
signal_status(:IN_EVAL) do
|
491
|
+
begin
|
492
|
+
line.untaint
|
493
|
+
@context.evaluate(line, line_no, exception: exc)
|
494
|
+
output_value if @context.echo?
|
495
|
+
rescue Interrupt => exc
|
496
|
+
rescue SystemExit, SignalException
|
497
|
+
raise
|
498
|
+
rescue Exception => exc
|
499
|
+
else
|
500
|
+
exc = nil
|
501
|
+
next
|
502
|
+
end
|
503
|
+
handle_exception(exc)
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
def handle_exception(exc)
|
509
|
+
if exc.backtrace && exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
|
510
|
+
!(SyntaxError === exc)
|
511
|
+
irb_bug = true
|
512
|
+
else
|
513
|
+
irb_bug = false
|
514
|
+
end
|
515
|
+
|
516
|
+
if STDOUT.tty?
|
517
|
+
attr = ATTR_TTY
|
518
|
+
print "#{attr[1]}Traceback#{attr[]} (most recent call last):\n"
|
519
|
+
else
|
520
|
+
attr = ATTR_PLAIN
|
521
|
+
end
|
522
|
+
messages = []
|
523
|
+
lasts = []
|
524
|
+
levels = 0
|
525
|
+
if exc.backtrace
|
526
|
+
count = 0
|
527
|
+
exc.backtrace.each do |m|
|
528
|
+
m = @context.workspace.filter_backtrace(m) or next unless irb_bug
|
529
|
+
count += 1
|
530
|
+
if attr == ATTR_TTY
|
531
|
+
m = sprintf("%9d: from %s", count, m)
|
532
|
+
else
|
533
|
+
m = "\tfrom #{m}"
|
534
|
+
end
|
535
|
+
if messages.size < @context.back_trace_limit
|
536
|
+
messages.push(m)
|
537
|
+
elsif lasts.size < @context.back_trace_limit
|
538
|
+
lasts.push(m).shift
|
539
|
+
levels += 1
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
if attr == ATTR_TTY
|
544
|
+
unless lasts.empty?
|
545
|
+
puts lasts.reverse
|
546
|
+
printf "... %d levels...\n", levels if levels > 0
|
547
|
+
end
|
548
|
+
puts messages.reverse
|
549
|
+
end
|
550
|
+
m = exc.to_s.split(/\n/)
|
551
|
+
print "#{attr[1]}#{exc.class} (#{attr[4]}#{m.shift}#{attr[0, 1]})#{attr[]}\n"
|
552
|
+
puts m.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
|
553
|
+
if attr == ATTR_PLAIN
|
554
|
+
puts messages
|
555
|
+
unless lasts.empty?
|
556
|
+
puts lasts
|
557
|
+
printf "... %d levels...\n", levels if levels > 0
|
558
|
+
end
|
559
|
+
end
|
560
|
+
print "Maybe IRB bug!\n" if irb_bug
|
561
|
+
end
|
562
|
+
|
563
|
+
# Evaluates the given block using the given +path+ as the Context#irb_path
|
564
|
+
# and +name+ as the Context#irb_name.
|
565
|
+
#
|
566
|
+
# Used by the irb command +source+, see IRB@IRB+Sessions for more
|
567
|
+
# information.
|
568
|
+
def suspend_name(path = nil, name = nil)
|
569
|
+
@context.irb_path, back_path = path, @context.irb_path if path
|
570
|
+
@context.irb_name, back_name = name, @context.irb_name if name
|
571
|
+
begin
|
572
|
+
yield back_path, back_name
|
573
|
+
ensure
|
574
|
+
@context.irb_path = back_path if path
|
575
|
+
@context.irb_name = back_name if name
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
# Evaluates the given block using the given +workspace+ as the
|
580
|
+
# Context#workspace.
|
581
|
+
#
|
582
|
+
# Used by the irb command +irb_load+, see IRB@IRB+Sessions for more
|
583
|
+
# information.
|
584
|
+
def suspend_workspace(workspace)
|
585
|
+
@context.workspace, back_workspace = workspace, @context.workspace
|
586
|
+
begin
|
587
|
+
yield back_workspace
|
588
|
+
ensure
|
589
|
+
@context.workspace = back_workspace
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
# Evaluates the given block using the given +input_method+ as the
|
594
|
+
# Context#io.
|
595
|
+
#
|
596
|
+
# Used by the irb commands +source+ and +irb_load+, see IRB@IRB+Sessions
|
597
|
+
# for more information.
|
598
|
+
def suspend_input_method(input_method)
|
599
|
+
back_io = @context.io
|
600
|
+
@context.instance_eval{@io = input_method}
|
601
|
+
begin
|
602
|
+
yield back_io
|
603
|
+
ensure
|
604
|
+
@context.instance_eval{@io = back_io}
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
# Evaluates the given block using the given +context+ as the Context.
|
609
|
+
def suspend_context(context)
|
610
|
+
@context, back_context = context, @context
|
611
|
+
begin
|
612
|
+
yield back_context
|
613
|
+
ensure
|
614
|
+
@context = back_context
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
# Handler for the signal SIGINT, see Kernel#trap for more information.
|
619
|
+
def signal_handle
|
620
|
+
unless @context.ignore_sigint?
|
621
|
+
print "\nabort!\n" if @context.verbose?
|
622
|
+
exit
|
623
|
+
end
|
624
|
+
|
625
|
+
case @signal_status
|
626
|
+
when :IN_INPUT
|
627
|
+
print "^C\n"
|
628
|
+
raise RubyLex::TerminateLineInput
|
629
|
+
when :IN_EVAL
|
630
|
+
IRB.irb_abort(self)
|
631
|
+
when :IN_LOAD
|
632
|
+
IRB.irb_abort(self, LoadAbort)
|
633
|
+
when :IN_IRB
|
634
|
+
# ignore
|
635
|
+
else
|
636
|
+
# ignore other cases as well
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
# Evaluates the given block using the given +status+.
|
641
|
+
def signal_status(status)
|
642
|
+
return yield if @signal_status == :IN_LOAD
|
643
|
+
|
644
|
+
signal_status_back = @signal_status
|
645
|
+
@signal_status = status
|
646
|
+
begin
|
647
|
+
yield
|
648
|
+
ensure
|
649
|
+
@signal_status = signal_status_back
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
def prompt(prompt, ltype, indent, line_no) # :nodoc:
|
654
|
+
p = prompt.dup
|
655
|
+
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
656
|
+
case $2
|
657
|
+
when "N"
|
658
|
+
@context.irb_name
|
659
|
+
when "m"
|
660
|
+
@context.main.to_s
|
661
|
+
when "M"
|
662
|
+
@context.main.inspect
|
663
|
+
when "l"
|
664
|
+
ltype
|
665
|
+
when "i"
|
666
|
+
if $1
|
667
|
+
format("%" + $1 + "d", indent)
|
668
|
+
else
|
669
|
+
indent.to_s
|
670
|
+
end
|
671
|
+
when "n"
|
672
|
+
if $1
|
673
|
+
format("%" + $1 + "d", line_no)
|
674
|
+
else
|
675
|
+
line_no.to_s
|
676
|
+
end
|
677
|
+
when "%"
|
678
|
+
"%"
|
679
|
+
end
|
680
|
+
end
|
681
|
+
p
|
682
|
+
end
|
683
|
+
|
684
|
+
def output_value # :nodoc:
|
685
|
+
printf @context.return_format, @context.inspect_last_value
|
686
|
+
end
|
687
|
+
|
688
|
+
# Outputs the local variables to this current session, including
|
689
|
+
# #signal_status and #context, using IRB::Locale.
|
690
|
+
def inspect
|
691
|
+
ary = []
|
692
|
+
for iv in instance_variables
|
693
|
+
case (iv = iv.to_s)
|
694
|
+
when "@signal_status"
|
695
|
+
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
696
|
+
when "@context"
|
697
|
+
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
698
|
+
else
|
699
|
+
ary.push format("%s=%s", iv, eval(iv))
|
700
|
+
end
|
701
|
+
end
|
702
|
+
format("#<%s: %s>", self.class, ary.join(", "))
|
703
|
+
end
|
704
|
+
|
705
|
+
ATTR_TTY = "\e[%sm"
|
706
|
+
def ATTR_TTY.[](*a) self % a.join(";"); end
|
707
|
+
ATTR_PLAIN = ""
|
708
|
+
def ATTR_PLAIN.[](*) self; end
|
709
|
+
end
|
710
|
+
|
711
|
+
def @CONF.inspect
|
712
|
+
IRB.version unless self[:VERSION]
|
713
|
+
|
714
|
+
array = []
|
715
|
+
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
716
|
+
case k
|
717
|
+
when :MAIN_CONTEXT, :__TMP__EHV__
|
718
|
+
array.push format("CONF[:%s]=...myself...", k.id2name)
|
719
|
+
when :PROMPT
|
720
|
+
s = v.collect{
|
721
|
+
|kk, vv|
|
722
|
+
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
723
|
+
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
724
|
+
}
|
725
|
+
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
726
|
+
else
|
727
|
+
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
728
|
+
end
|
729
|
+
end
|
730
|
+
array.join("\n")
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
class Binding
|
735
|
+
# Opens an IRB session where +binding.irb+ is called which allows for
|
736
|
+
# interactive debugging. You can call any methods or variables available in
|
737
|
+
# the current scope, and mutate state if you need to.
|
738
|
+
#
|
739
|
+
#
|
740
|
+
# Given a Ruby file called +potato.rb+ containing the following code:
|
741
|
+
#
|
742
|
+
# class Potato
|
743
|
+
# def initialize
|
744
|
+
# @cooked = false
|
745
|
+
# binding.irb
|
746
|
+
# puts "Cooked potato: #{@cooked}"
|
747
|
+
# end
|
748
|
+
# end
|
749
|
+
#
|
750
|
+
# Potato.new
|
751
|
+
#
|
752
|
+
# Running +ruby potato.rb+ will open an IRB session where +binding.irb+ is
|
753
|
+
# called, and you will see the following:
|
754
|
+
#
|
755
|
+
# $ ruby potato.rb
|
756
|
+
#
|
757
|
+
# From: potato.rb @ line 4 :
|
758
|
+
#
|
759
|
+
# 1: class Potato
|
760
|
+
# 2: def initialize
|
761
|
+
# 3: @cooked = false
|
762
|
+
# => 4: binding.irb
|
763
|
+
# 5: puts "Cooked potato: #{@cooked}"
|
764
|
+
# 6: end
|
765
|
+
# 7: end
|
766
|
+
# 8:
|
767
|
+
# 9: Potato.new
|
768
|
+
#
|
769
|
+
# irb(#<Potato:0x00007feea1916670>):001:0>
|
770
|
+
#
|
771
|
+
# You can type any valid Ruby code and it will be evaluated in the current
|
772
|
+
# context. This allows you to debug without having to run your code repeatedly:
|
773
|
+
#
|
774
|
+
# irb(#<Potato:0x00007feea1916670>):001:0> @cooked
|
775
|
+
# => false
|
776
|
+
# irb(#<Potato:0x00007feea1916670>):002:0> self.class
|
777
|
+
# => Potato
|
778
|
+
# irb(#<Potato:0x00007feea1916670>):003:0> caller.first
|
779
|
+
# => ".../2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval'"
|
780
|
+
# irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
|
781
|
+
# => true
|
782
|
+
#
|
783
|
+
# You can exit the IRB session with the `exit` command. Note that exiting will
|
784
|
+
# resume execution where +binding.irb+ had paused it, as you can see from the
|
785
|
+
# output printed to standard output in this example:
|
786
|
+
#
|
787
|
+
# irb(#<Potato:0x00007feea1916670>):005:0> exit
|
788
|
+
# Cooked potato: true
|
789
|
+
#
|
790
|
+
#
|
791
|
+
# See IRB@IRB+Usage for more information.
|
792
|
+
def irb
|
793
|
+
IRB.setup(eval("__FILE__"), argv: [])
|
794
|
+
workspace = IRB::WorkSpace.new(self)
|
795
|
+
STDOUT.print(workspace.code_around_binding)
|
796
|
+
IRB::Irb.new(workspace).run(IRB.conf)
|
797
|
+
end
|
798
|
+
end
|