mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00

irb.rb: preserve ARGV on binding.irb This is not perfectly good solution (at least we don't want to have ARGV as default value of `argv` argument), but unfortunately IRB.setup and IRB.parse_opts are public methods and we can't make breaking change to those methods. We may deprecate using them and then make them private in the future, but the removal should not be in Ruby 2.5. So I kept their interface for now. [Bug #14162] [close GH-1770] * properties. irb/init.rb: make sure ARGV refers to toplevel one irb/test_init.rb: add test to ensure $0 is not changed. At first `ARGV.unshift('something')` was suggested for r61149, but it wasn't sufficient because it modifies $0. Not only to preserve ARGV, but also r61149 intends to preserve $0. This test prevents future breakage of the behavior. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@62185 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
305 lines
7.7 KiB
Ruby
305 lines
7.7 KiB
Ruby
# frozen_string_literal: false
|
|
#
|
|
# irb/init.rb - irb initialize module
|
|
# $Release Version: 0.9.6$
|
|
# $Revision$
|
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
|
#
|
|
# --
|
|
#
|
|
#
|
|
#
|
|
|
|
module IRB # :nodoc:
|
|
|
|
# initialize config
|
|
def IRB.setup(ap_path, argv: ::ARGV)
|
|
IRB.init_config(ap_path)
|
|
IRB.init_error
|
|
IRB.parse_opts(argv: argv)
|
|
IRB.run_config
|
|
IRB.load_modules
|
|
|
|
unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
|
|
IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
|
|
end
|
|
end
|
|
|
|
# @CONF default setting
|
|
def IRB.init_config(ap_path)
|
|
# class instance variables
|
|
@TRACER_INITIALIZED = false
|
|
|
|
# default configurations
|
|
unless ap_path and @CONF[:AP_NAME]
|
|
ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
|
|
end
|
|
@CONF[:AP_NAME] = File::basename(ap_path, ".rb")
|
|
|
|
@CONF[:IRB_NAME] = "irb"
|
|
@CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)
|
|
|
|
@CONF[:RC] = true
|
|
@CONF[:LOAD_MODULES] = []
|
|
@CONF[:IRB_RC] = nil
|
|
|
|
@CONF[:MATH_MODE] = false
|
|
@CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
|
|
@CONF[:INSPECT_MODE] = true
|
|
@CONF[:USE_TRACER] = false
|
|
@CONF[:USE_LOADER] = false
|
|
@CONF[:IGNORE_SIGINT] = true
|
|
@CONF[:IGNORE_EOF] = false
|
|
@CONF[:ECHO] = nil
|
|
@CONF[:VERBOSE] = nil
|
|
|
|
@CONF[:EVAL_HISTORY] = nil
|
|
@CONF[:SAVE_HISTORY] = nil
|
|
|
|
@CONF[:BACK_TRACE_LIMIT] = 16
|
|
|
|
@CONF[:PROMPT] = {
|
|
:NULL => {
|
|
:PROMPT_I => nil,
|
|
:PROMPT_N => nil,
|
|
:PROMPT_S => nil,
|
|
:PROMPT_C => nil,
|
|
:RETURN => "%s\n"
|
|
},
|
|
: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"
|
|
},
|
|
:CLASSIC => {
|
|
: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"
|
|
},
|
|
:SIMPLE => {
|
|
:PROMPT_I => ">> ",
|
|
:PROMPT_N => ">> ",
|
|
:PROMPT_S => nil,
|
|
:PROMPT_C => "?> ",
|
|
:RETURN => "=> %s\n"
|
|
},
|
|
:INF_RUBY => {
|
|
:PROMPT_I => "%N(%m):%03n:%i> ",
|
|
:PROMPT_N => nil,
|
|
:PROMPT_S => nil,
|
|
:PROMPT_C => nil,
|
|
:RETURN => "%s\n",
|
|
:AUTO_INDENT => true
|
|
},
|
|
:XMP => {
|
|
:PROMPT_I => nil,
|
|
:PROMPT_N => nil,
|
|
:PROMPT_S => nil,
|
|
:PROMPT_C => nil,
|
|
:RETURN => " ==>%s\n"
|
|
}
|
|
}
|
|
|
|
@CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
|
|
@CONF[:AUTO_INDENT] = false
|
|
|
|
@CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
|
|
@CONF[:SINGLE_IRB] = false
|
|
|
|
@CONF[:LC_MESSAGES] = Locale.new
|
|
|
|
@CONF[:AT_EXIT] = []
|
|
|
|
@CONF[:DEBUG_LEVEL] = 0
|
|
end
|
|
|
|
def IRB.init_error
|
|
@CONF[:LC_MESSAGES].load("irb/error.rb")
|
|
end
|
|
|
|
# option analyzing
|
|
def IRB.parse_opts(argv: ::ARGV)
|
|
load_path = []
|
|
while opt = argv.shift
|
|
case opt
|
|
when "-f"
|
|
@CONF[:RC] = false
|
|
when "-m"
|
|
@CONF[:MATH_MODE] = true
|
|
when "-d"
|
|
$DEBUG = true
|
|
$VERBOSE = true
|
|
when "-w"
|
|
$VERBOSE = true
|
|
when /^-W(.+)?/
|
|
opt = $1 || argv.shift
|
|
case opt
|
|
when "0"
|
|
$VERBOSE = nil
|
|
when "1"
|
|
$VERBOSE = false
|
|
else
|
|
$VERBOSE = true
|
|
end
|
|
when /^-r(.+)?/
|
|
opt = $1 || argv.shift
|
|
@CONF[:LOAD_MODULES].push opt if opt
|
|
when /^-I(.+)?/
|
|
opt = $1 || argv.shift
|
|
load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
|
|
when '-U'
|
|
set_encoding("UTF-8", "UTF-8")
|
|
when /^-E(.+)?/, /^--encoding(?:=(.+))?/
|
|
opt = $1 || argv.shift
|
|
set_encoding(*opt.split(':', 2))
|
|
when "--inspect"
|
|
if /^-/ !~ argv.first
|
|
@CONF[:INSPECT_MODE] = argv.shift
|
|
else
|
|
@CONF[:INSPECT_MODE] = true
|
|
end
|
|
when "--noinspect"
|
|
@CONF[:INSPECT_MODE] = false
|
|
when "--readline"
|
|
@CONF[:USE_READLINE] = true
|
|
when "--noreadline"
|
|
@CONF[:USE_READLINE] = false
|
|
when "--echo"
|
|
@CONF[:ECHO] = true
|
|
when "--noecho"
|
|
@CONF[:ECHO] = false
|
|
when "--verbose"
|
|
@CONF[:VERBOSE] = true
|
|
when "--noverbose"
|
|
@CONF[:VERBOSE] = false
|
|
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
|
|
opt = $1 || argv.shift
|
|
prompt_mode = opt.upcase.tr("-", "_").intern
|
|
@CONF[:PROMPT_MODE] = prompt_mode
|
|
when "--noprompt"
|
|
@CONF[:PROMPT_MODE] = :NULL
|
|
when "--inf-ruby-mode"
|
|
@CONF[:PROMPT_MODE] = :INF_RUBY
|
|
when "--sample-book-mode", "--simple-prompt"
|
|
@CONF[:PROMPT_MODE] = :SIMPLE
|
|
when "--tracer"
|
|
@CONF[:USE_TRACER] = true
|
|
when /^--back-trace-limit(?:=(.+))?/
|
|
@CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i
|
|
when /^--context-mode(?:=(.+))?/
|
|
@CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
|
|
when "--single-irb"
|
|
@CONF[:SINGLE_IRB] = true
|
|
when /^--irb_debug(?:=(.+))?/
|
|
@CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i
|
|
when "-v", "--version"
|
|
print IRB.version, "\n"
|
|
exit 0
|
|
when "-h", "--help"
|
|
require "irb/help"
|
|
IRB.print_usage
|
|
exit 0
|
|
when "--"
|
|
if opt = argv.shift
|
|
@CONF[:SCRIPT] = opt
|
|
$0 = opt
|
|
end
|
|
break
|
|
when /^-/
|
|
IRB.fail UnrecognizedSwitch, opt
|
|
else
|
|
@CONF[:SCRIPT] = opt
|
|
$0 = opt
|
|
break
|
|
end
|
|
end
|
|
load_path.collect! do |path|
|
|
/\A\.\// =~ path ? path : File.expand_path(path)
|
|
end
|
|
$LOAD_PATH.unshift(*load_path)
|
|
|
|
end
|
|
|
|
# running config
|
|
def IRB.run_config
|
|
if @CONF[:RC]
|
|
begin
|
|
load rc_file
|
|
rescue LoadError, Errno::ENOENT
|
|
rescue # StandardError, ScriptError
|
|
print "load error: #{rc_file}\n"
|
|
print $!.class, ": ", $!, "\n"
|
|
for err in $@[0, $@.size - 2]
|
|
print "\t", err, "\n"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
IRBRC_EXT = "rc"
|
|
def IRB.rc_file(ext = IRBRC_EXT)
|
|
if !@CONF[:RC_NAME_GENERATOR]
|
|
rc_file_generators do |rcgen|
|
|
@CONF[:RC_NAME_GENERATOR] ||= rcgen
|
|
if File.exist?(rcgen.call(IRBRC_EXT))
|
|
@CONF[:RC_NAME_GENERATOR] = rcgen
|
|
break
|
|
end
|
|
end
|
|
end
|
|
case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
|
|
when String
|
|
return rc_file
|
|
else
|
|
IRB.fail IllegalRCNameGenerator
|
|
end
|
|
end
|
|
|
|
# enumerate possible rc-file base name generators
|
|
def IRB.rc_file_generators
|
|
if irbrc = ENV["IRBRC"]
|
|
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
|
|
end
|
|
if home = ENV["HOME"]
|
|
yield proc{|rc| home+"/.irb#{rc}"}
|
|
end
|
|
home = Dir.pwd
|
|
yield proc{|rc| home+"/.irb#{rc}"}
|
|
yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
|
|
yield proc{|rc| home+"/_irb#{rc}"}
|
|
yield proc{|rc| home+"/$irb#{rc}"}
|
|
end
|
|
|
|
# loading modules
|
|
def IRB.load_modules
|
|
for m in @CONF[:LOAD_MODULES]
|
|
begin
|
|
require m
|
|
rescue LoadError => err
|
|
warn err.backtrace[0] << ":#{err.class}: #{err}"
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
DefaultEncodings = Struct.new(:external, :internal)
|
|
class << IRB
|
|
private
|
|
def set_encoding(extern, intern = nil)
|
|
verbose, $VERBOSE = $VERBOSE, nil
|
|
Encoding.default_external = extern unless extern.nil? || extern.empty?
|
|
Encoding.default_internal = intern unless intern.nil? || intern.empty?
|
|
@CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
|
|
[$stdin, $stdout, $stderr].each do |io|
|
|
io.set_encoding(extern, intern)
|
|
end
|
|
@CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
|
|
ensure
|
|
$VERBOSE = verbose
|
|
end
|
|
end
|
|
end
|