[ruby/irb] Support --noscript option to not use first non-option argument as script

Also add --script option to turn the option back on.

Previously there wasn't a way to get an interactive IRB session
and access arguments provided on the command line.

Additionally, handle `-` as script as stdin. In Unix-like tools, `-`
means to take standard input instead of a file.  This doesn't
result in exactly the same output for:

```
echo 'p ARGV' > args.rb; irb args.rb a b c
```

and

```
echo 'p ARGV' | irb - a b c
```

Due to how irb handles whether stdin is a tty.

However, this change allows use of `-` as a argument, instead of
giving an unrecognized switch error. This required some small
changes to context.rb (to handle `-` as standard input) and
input-method.rb (to have FileInputMethod accept IO arguments in
addition to strings).

Implements [Feature #15371]

https://github.com/ruby/irb/commit/4192683ba2
This commit is contained in:
Jeremy Evans 2022-09-17 02:25:15 +09:00 committed by git
parent 64200990c4
commit b07db96744
5 changed files with 64 additions and 5 deletions

View File

@ -115,6 +115,10 @@ module IRB
end end
@io = StdioInputMethod.new unless @io @io = StdioInputMethod.new unless @io
when '-'
@io = FileInputMethod.new($stdin)
@irb_name = '-'
@irb_path = '-'
when String when String
@io = FileInputMethod.new(input_method) @io = FileInputMethod.new(input_method)
@irb_name = File.basename(input_method) @irb_name = File.basename(input_method)

View File

@ -289,6 +289,10 @@ module IRB # :nodoc:
@CONF[:PROMPT_MODE] = prompt_mode @CONF[:PROMPT_MODE] = prompt_mode
when "--noprompt" when "--noprompt"
@CONF[:PROMPT_MODE] = :NULL @CONF[:PROMPT_MODE] = :NULL
when "--script"
noscript = false
when "--noscript"
noscript = true
when "--inf-ruby-mode" when "--inf-ruby-mode"
@CONF[:PROMPT_MODE] = :INF_RUBY @CONF[:PROMPT_MODE] = :INF_RUBY
when "--sample-book-mode", "--simple-prompt" when "--sample-book-mode", "--simple-prompt"
@ -309,16 +313,20 @@ module IRB # :nodoc:
IRB.print_usage IRB.print_usage
exit 0 exit 0
when "--" when "--"
if opt = argv.shift if !noscript && (opt = argv.shift)
@CONF[:SCRIPT] = opt @CONF[:SCRIPT] = opt
$0 = opt $0 = opt
end end
break break
when /^-/ when /^-./
fail UnrecognizedSwitch, opt fail UnrecognizedSwitch, opt
else else
@CONF[:SCRIPT] = opt if noscript
$0 = opt argv.unshift(opt)
else
@CONF[:SCRIPT] = opt
$0 = opt
end
break break
end end
end end

View File

@ -137,7 +137,7 @@ module IRB
# Creates a new input method object # Creates a new input method object
def initialize(file) def initialize(file)
super super
@io = IRB::MagicFile.open(file) @io = file.is_a?(IO) ? file : IRB::MagicFile.open(file)
@external_encoding = @io.external_encoding @external_encoding = @io.external_encoding
end end
# The file name of this input method, usually given during initialization. # The file name of this input method, usually given during initialization.

View File

@ -38,6 +38,8 @@ Usage: irb.rb [options] [programfile] [arguments]
--sample-book-mode, --simple-prompt --sample-book-mode, --simple-prompt
Set prompt mode to 'simple'. Set prompt mode to 'simple'.
--noprompt Don't output prompt. --noprompt Don't output prompt.
--script Script mode (default, treat first argument as script)
--noscript No script mode (leave arguments in argv)
--single-irb Share self with sub-irb. --single-irb Share self with sub-irb.
--tracer Show stack trace for each command. --tracer Show stack trace for each command.
--back-trace-limit n[=16] --back-trace-limit n[=16]

View File

@ -16,6 +16,7 @@ module TestIRB
def teardown def teardown
ENV.update(@backup_env) ENV.update(@backup_env)
FileUtils.rm_rf(@tmpdir) FileUtils.rm_rf(@tmpdir)
IRB.conf.delete(:SCRIPT)
end end
def test_setup_with_argv_preserves_global_argv def test_setup_with_argv_preserves_global_argv
@ -87,6 +88,50 @@ module TestIRB
IRB.conf[:USE_COLORIZE] = orig_use_colorize IRB.conf[:USE_COLORIZE] = orig_use_colorize
end end
def test_noscript
argv = %w[--noscript -- -f]
IRB.setup(eval("__FILE__"), argv: argv)
assert_nil IRB.conf[:SCRIPT]
assert_equal(['-f'], argv)
argv = %w[--noscript -- a]
IRB.setup(eval("__FILE__"), argv: argv)
assert_nil IRB.conf[:SCRIPT]
assert_equal(['a'], argv)
argv = %w[--noscript a]
IRB.setup(eval("__FILE__"), argv: argv)
assert_nil IRB.conf[:SCRIPT]
assert_equal(['a'], argv)
argv = %w[--script --noscript a]
IRB.setup(eval("__FILE__"), argv: argv)
assert_nil IRB.conf[:SCRIPT]
assert_equal(['a'], argv)
argv = %w[--noscript --script a]
IRB.setup(eval("__FILE__"), argv: argv)
assert_equal('a', IRB.conf[:SCRIPT])
assert_equal([], argv)
end
def test_dash
argv = %w[-]
IRB.setup(eval("__FILE__"), argv: argv)
assert_equal('-', IRB.conf[:SCRIPT])
assert_equal([], argv)
argv = %w[-- -]
IRB.setup(eval("__FILE__"), argv: argv)
assert_equal('-', IRB.conf[:SCRIPT])
assert_equal([], argv)
argv = %w[-- - -f]
IRB.setup(eval("__FILE__"), argv: argv)
assert_equal('-', IRB.conf[:SCRIPT])
assert_equal(['-f'], argv)
end
private private
def with_argv(argv) def with_argv(argv)