diff --git a/doc/COMMAND_LINE_OPTIONS.md b/doc/COMMAND_LINE_OPTIONS.md index 08077ff1b..f4203ff1e 100644 --- a/doc/COMMAND_LINE_OPTIONS.md +++ b/doc/COMMAND_LINE_OPTIONS.md @@ -21,7 +21,7 @@ These are the IRB command-line options, with links to explanatory text: - `--colorize`: Use {color-highlighting}[rdoc-ref:IRB@Color+Highlighting] for input and output. - `--context-mode _n_`: Select method to create Binding object - for new {workspace}[rdoc-ref:IRB@Commands]; `n` in range `0..4`. + for new {workspace}[rdoc-ref:IRB@Commands]; `n` in range `0..5`. - `--echo`: Print ({echo}[rdoc-ref:IRB@Return-Value+Printing+-28Echoing-29]) return values. - `--extra-doc-dir _dirpath_`: diff --git a/doc/irb/irb.rd.ja b/doc/irb/irb.rd.ja index c51e0bd60..0733a276b 100644 --- a/doc/irb/irb.rd.ja +++ b/doc/irb/irb.rd.ja @@ -48,7 +48,7 @@ irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本 -w ruby -w と同じ. -W[level=2] ruby -W と同じ. --context-mode n 新しいワークスペースを作成した時に関連する Binding - オブジェクトの作成方法を 0 から 3 のいずれかに設定する. + オブジェクトの作成方法を 0 から 5 のいずれかに設定する. --echo 実行結果を表示する(デフォルト). --noecho 実行結果を表示しない. --echo-on-assignment diff --git a/lib/irb/lc/help-message b/lib/irb/lc/help-message index 37347306e..94a27cdf0 100644 --- a/lib/irb/lc/help-message +++ b/lib/irb/lc/help-message @@ -9,7 +9,7 @@ Usage: irb.rb [options] [programfile] [arguments] -w Suppress warnings (same as 'ruby -w'). -W[level=2] Set warning level: 0=silence, 1=medium, 2=verbose (same as 'ruby -W'). - --context-mode n Set n[0-4] to method to create Binding Object, + --context-mode n Set n[0-5] to method to create Binding Object, when new workspace was created. --extra-doc-dir Add an extra doc dir for the doc dialog. --echo Show result (default). diff --git a/lib/irb/lc/ja/help-message b/lib/irb/lc/ja/help-message index 844c67bbb..c703ea2c8 100644 --- a/lib/irb/lc/ja/help-message +++ b/lib/irb/lc/ja/help-message @@ -8,7 +8,7 @@ Usage: irb.rb [options] [programfile] [arguments] -w ruby -w と同じ. -W[level=2] ruby -W と同じ. --context-mode n 新しいワークスペースを作成した時に関連する Binding - オブジェクトの作成方法を 0 から 4 のいずれかに設定する. + オブジェクトの作成方法を 0 から 5 のいずれかに設定する. --extra-doc-dir 指定したディレクトリのドキュメントを追加で読み込む. --echo 実行結果を表示する(デフォルト). --noecho 実行結果を表示しない. diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb index ced9d7866..9fef8f86a 100644 --- a/lib/irb/workspace.rb +++ b/lib/irb/workspace.rb @@ -55,6 +55,15 @@ def initialize(*main) # Note that this will typically be IRB::TOPLEVEL_BINDING # This is to avoid RubyGems' local variables (see issue #17623) @binding = TOPLEVEL_BINDING.dup + + when 5 # binding in Ruby::Box + unless defined?(Ruby::Box) + puts 'Context-mode 5 (binding in Ruby::Box) requires Ruby 4.0 or later.' + raise NameError, 'Ruby::Box not defined' + end + + puts 'Context-mode 5 (binding in Ruby::Box) is experimental. It may be removed or changed without notice.' + @binding = Ruby::Box.new.eval('Kernel.binding') end end diff --git a/test/irb/helper.rb b/test/irb/helper.rb index 6a0183104..ead934a45 100644 --- a/test/irb/helper.rb +++ b/test/irb/helper.rb @@ -139,7 +139,7 @@ def teardown end end - def run_ruby_file(&block) + def run_ruby_file(timeout: TIMEOUT_SEC, &block) cmd = [EnvUtil.rubybin, "-I", LIB, @ruby_file.to_path] tmp_dir = Dir.mktmpdir @@ -156,7 +156,7 @@ def run_ruby_file(&block) envs_for_spawn = @envs.merge('TERM' => 'dumb', 'TEST_IRB_FORCE_INTERACTIVE' => 'true') PTY.spawn(envs_for_spawn, *cmd) do |read, write, pid| - Timeout.timeout(TIMEOUT_SEC) do + Timeout.timeout(timeout) do while line = safe_gets(read) lines << line diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb index 30f3ad5a0..1b0290d0c 100644 --- a/test/irb/test_irb.rb +++ b/test/irb/test_irb.rb @@ -963,4 +963,34 @@ def bar end end end + + class ContextModeTest < TestIRB::IntegrationTestCase + # RUBY_BOX=1 may need more time to start IRB + TIMEOUT_SEC = TestIRB::IntegrationTestCase::TIMEOUT_SEC + 5 + + def test_context_mode_ruby_box + omit if RUBY_VERSION < "4.0.0" + @envs['RUBY_BOX'] = '1' + + write_rc <<~'RUBY' + IRB.conf[:CONTEXT_MODE] = 5 + RUBY + + write_ruby <<~'RUBY' + require 'irb' + puts 'binding.irb' # Mark for breakpoint trigger + IRB.start + p answer2: 1 + 2 + RUBY + + output = run_ruby_file(timeout: TIMEOUT_SEC) do + type 'class Integer; def +(_other) = 42; end' + type 'p answer1: 1 + 2' + type 'exit' + end + + assert_include(output, '{answer1: 42}') + assert_include(output, '{answer2: 3}') + end + end end