# frozen_string_literal: false
# irb.rb - irb main module
# $Release Version: 0.9.6 $
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
require_relative "irb/init"
require_relative "irb/context"
require_relative "irb/extend-command"
require_relative "irb/ruby-lex"
require_relative "irb/input-method"
require_relative "irb/locale"
require_relative "irb/color"
require_relative "irb/version"
require_relative "irb/easter-egg"
# IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby
# expressions read from the standard input.
# The +irb+ command from your shell will start the interpreter.
# Use of irb is easy if you know Ruby.
# When executing irb, prompts are displayed as follows. Then, enter the Ruby
# expression. An input is executed when it is syntactically complete.
# irb(main):002:0> class Foo
# irb(main):003:1> def foo
# irb(main):004:2> print 1
# The singleline editor module or multiline editor module can be used with irb.
# Use of multiline editor is default if it's installed.
# == Command line options
# Usage: irb.rb [options] [programfile] [arguments]
# -f Suppress read of ~/.irbrc
# -d Set $DEBUG to true (same as `ruby -d')
# -r load-module Same as `ruby -r'
# -I path Specify $LOAD_PATH directory
# -E enc Same as `ruby -E`
# -W[level=2] Same as `ruby -W`
# --inspect Use `inspect' for output (default except for bc mode)
# --noinspect Don't use inspect for output
# --multiline Use multiline editor module
# --nomultiline Don't use multiline editor module
# --singleline Use singleline editor module
# --nosingleline Don't use singleline editor module
# --colorize Use colorization
# --nocolorize Don't use colorization
# --prompt-mode prompt-mode
# Switch prompt mode. Pre-defined prompt modes are
# `default', `simple', `xmp' and `inf-ruby'
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
# Suppresses --multiline and --singleline.
# --simple-prompt Simple prompt mode
# --noprompt No prompt mode
# --tracer Display trace for each execution of commands.
# Display backtrace top n and tail n. The default
# -v, --version Print the version of irb
# IRB reads from <code>~/.irbrc</code> when it's invoked.
# If <code>~/.irbrc</code> doesn't exist, +irb+ will try to read in the following order:
# The following are alternatives to the command line options. To use them type
# as follows in an +irb+ session:
# IRB.conf[:IRB_NAME]="irb"
# IRB.conf[:INSPECT_MODE]=nil
# IRB.conf[:IRB_RC] = nil
# IRB.conf[:BACK_TRACE_LIMIT]=16
# IRB.conf[:USE_LOADER] = false
# IRB.conf[:USE_MULTILINE] = nil
# IRB.conf[:USE_SINGLELINE] = nil
# IRB.conf[:USE_COLORIZE] = true
# IRB.conf[:USE_TRACER] = false
# IRB.conf[:IGNORE_SIGINT] = true
# IRB.conf[:IGNORE_EOF] = false
# IRB.conf[:PROMPT_MODE] = :DEFAULT
# IRB.conf[:PROMPT] = {...}
# To disable auto-indent mode in irb, add the following to your +.irbrc+:
# IRB.conf[:AUTO_INDENT] = false
# To enable autocompletion for irb, add the following to your +.irbrc+:
# require 'irb/completion'
# By default, irb will store the last 1000 commands you used in
# <code>IRB.conf[:HISTORY_FILE]</code> (<code>~/.irb_history</code> by default).
# If you want to disable history, add the following to your +.irbrc+:
# IRB.conf[:SAVE_HISTORY] = nil
# See IRB::Context#save_history= for more information.
# The history of _results_ of commands evaluated is not stored by default,
# but can be turned on to be stored with this +.irbrc+ setting:
# IRB.conf[:EVAL_HISTORY] = <number>
# See IRB::Context#eval_history= and History class. The history of command
# results is not permanently saved in any file.
# == Customizing the IRB Prompt
# In order to customize the prompt, you can change the following Hash:
# This example can be used in your +.irbrc+
# IRB.conf[:PROMPT][:MY_PROMPT] = { # name of prompt mode
# :AUTO_INDENT => false, # disables auto-indent mode
# :PROMPT_I => ">> ", # simple prompt
# :PROMPT_S => nil, # prompt for continuated strings
# :PROMPT_C => nil, # prompt for continuated statement
# :RETURN => " ==>%s\n" # format to return value
# IRB.conf[:PROMPT_MODE] = :MY_PROMPT
# Or, invoke irb with the above prompt mode by:
# Constants +PROMPT_I+, +PROMPT_S+ and +PROMPT_C+ specify the format. In the
# prompt specification, some special strings are available:
# %N # command name which is running
# %m # to_s of main object (self)
# %M # inspect of main object (self)
# %l # type of string(", ', /, ]), `]' is inner %w[...]
# %NNi # indent level. NN is digits and means as same as printf("%NNd").
# For instance, the default prompt mode is defined as follows:
# IRB.conf[:PROMPT_MODE][:DEFAULT] = {
# :PROMPT_I => "%N(%m):%03n:%i> ",
# :PROMPT_N => "%N(%m):%03n:%i> ",
# :PROMPT_S => "%N(%m):%03n:%i%l ",
# :PROMPT_C => "%N(%m):%03n:%i* ",
# :RETURN => "%s\n" # used to printf
# irb comes with a number of available modes:
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
# # :PROMPT_N: ! '%N(%m):%03n:%i> '
# # :PROMPT_S: ! '%N(%m):%03n:%i%l '
# # :PROMPT_C: ! '%N(%m):%03n:%i* '
# # :PROMPT_I: ! '%N(%m):%03n:%i> '
# Because irb evaluates input immediately after it is syntactically complete,
# the results may be slightly different than directly using Ruby.
# IRB has a special feature, that allows you to manage many sessions at once.
# You can create new sessions with Irb.irb, and get a list of current sessions
# with the +jobs+ command in the prompt.
# JobManager provides commands to handle the current sessions:
# jobs # List of current sessions
# fg # Switches to the session of the given number
# kill # Kills the session with the given number
# The +exit+ command, or ::irb_exit, will quit the current session and call any
# exit hooks with IRB.irb_at_exit.
# A few commands for loading files within the session are also available:
# Loads a given file in the current session and displays the source lines,
# see IrbLoader#source_file
# Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
# Loads the given file similarly to Kernel#require
# The command line options, or IRB.conf, specify the default behavior of
# On the other hand, each conf in IRB@Command+line+options is used to
# individually configure IRB.irb.
# If a proc is set for <code>IRB.conf[:IRB_RC]</code>, its will be invoked after execution
# of that proc with the context of the current session as its argument. Each
# session can be configured using this mechanism.
# There are a few variables in every Irb session that can come in handy:
# The value command executed, as a local variable
# The history of evaluated commands. Available only if
# <code>IRB.conf[:EVAL_HISTORY]</code> is not +nil+ (which is the default).
# See also IRB::Context#eval_history= and IRB::History.
# <code>__[line_no]</code>::
# Returns the evaluation value at the given line number, +line_no+.
# If +line_no+ is a negative, the return value +line_no+ many lines before
# the most recent return value.
# === Example using IRB Sessions
# irb.1(main):001:0> jobs
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
# #1->irb#1 on main (#<Thread:0x40125d64> : running)
# # change the active session
# irb.1(main):002:0> fg 0
# # define class Foo in top-level session
# irb(main):002:0> class Foo;end
# # invoke a new session with the context of Foo
# irb(main):003:0> irb Foo
# irb.2(Foo):001:0> def foo
# irb.2(Foo):002:1> print 1
# # change the active session
# #0->irb on main (#<Thread:0x400fb7e4> : running)
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
# # check if Foo#foo is available
# irb(main):005:0> Foo.instance_methods #=> [:foo, ...]
# # change the active session
# # define Foo#bar in the context of Foo
# irb.2(Foo):005:0> def bar
# irb.2(Foo):006:1> print "bar"
# irb.2(Foo):010:0> Foo.instance_methods #=> [:bar, :foo, ...]
# # change the active session
# irb(main):007:0> f = Foo.new #=> #<Foo:0x4010af3c>
# # invoke a new session with the context of f (instance of Foo)
# irb.3(<Foo:0x4010af3c>):001:0> jobs
# #0->irb on main (#<Thread:0x400fb7e4> : stop)
# #1->irb#1 on main (#<Thread:0x40125d64> : stop)
# #2->irb#2 on Foo (#<Thread:0x4011d54c> : stop)
# #3->irb#3 on #<Foo:0x4010af3c> (#<Thread:0x4010a1e0> : running)
# irb.3(<Foo:0x4010af3c>):002:0> foo #=> 1 => nil
# irb.3(<Foo:0x4010af3c>):003:0> bar #=> bar => nil
# # kill jobs 1, 2, and 3
# irb.3(<Foo:0x4010af3c>):004:0> kill 1, 2, 3
# # list open sessions, should only include main session
# #0->irb on main (#<Thread:0x400fb7e4> : running)
# An exception raised by IRB.irb_abort
class Abort < Exception;end
# Displays current configuration.
# Modifying the configuration is achieved by sending a message to IRB.conf.
# See IRB@Configuration for more information.
# Returns the current version of IRB, including release version and last
if v = @CONF[:VERSION] then return v end
@CONF[:VERSION] = format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE)
# The current IRB::Context of the session, see IRB.conf
# irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
# foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
# Initializes IRB and creates a new Irb.irb object at the +TOPLEVEL_BINDING+
def IRB.start(ap_path = nil)
$0 = File::basename(ap_path, ".rb") if ap_path
irb = Irb.new(nil, @CONF[:SCRIPT])
# Calls each event hook of <code>IRB.conf[:TA_EXIT]</code> when the current session quits.
@CONF[:AT_EXIT].each{|hook| hook.call}
def IRB.irb_exit(irb, ret)
# Aborts then interrupts irb.
# Will raise an Abort exception, or the given +exception+.
def IRB.irb_abort(irb, exception = Abort)
irb.context.thread.raise exception, "abort then interrupt!"
raise exception, "abort then interrupt!"
ASSIGNMENT_NODE_TYPES = [
# Local, instance, global, class, constant, instance, and index assignment:
# Note: instance and index assignment expressions could also be written like:
# "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
# be parsed as :assign and echo will be suppressed, but the latter is
# parsed as a :method_add_arg and the output won't be suppressed
# Creates a new irb session
def initialize(workspace = nil, input_method = nil)
@context = Context.new(self, workspace, input_method)
@context.main.extend ExtendCommandBundle
conf[:IRB_RC].call(context) if conf[:IRB_RC]
conf[:MAIN_CONTEXT] = context
conf[:AT_EXIT].each{|hook| hook.call}
# Returns the current context of this irb session
# The lexer used by this irb session
# Evaluates input for this session.
|ltype, indent, continue, line_no|