Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/COMMAND_LINE_OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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_`:
Expand Down
2 changes: 1 addition & 1 deletion doc/irb/irb.rd.ja
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/irb/lc/help-message
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
2 changes: 1 addition & 1 deletion lib/irb/lc/ja/help-message
Original file line number Diff line number Diff line change
Expand Up @@ -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 実行結果を表示しない.
Expand Down
9 changes: 9 additions & 0 deletions lib/irb/workspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immediate exit will make IRB.start rescue do_something not work as expected

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')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we include a check for the Ruby version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be a constant defined check instead? If Ruby::Box doesn't exist, then we should warn that it's not available and that we'd fallback to the default behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a defined?(Ruby::Box) check.
I think if Ruby::Box is unavailable, it's OK or even safe to fail instead of fallback to default.

There is one more error case. If Box is not enabled by ENV['RUBY_BOX'], class Ruby::Box is defined but calling new throws RuntimeError.

'Ruby::Box#initialize': Ruby Box is disabled. Set RUBY_BOX=1 environment variable to use Ruby::Box. (RuntimeError)

end
end

Expand Down
4 changes: 2 additions & 2 deletions test/irb/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
30 changes: 30 additions & 0 deletions test/irb/test_irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be

Suggested change
TIMEOUT_SEC = TestIRB::IntegrationTestCase::TIMEOUT_SEC + 5
TIMEOUT_SEC = self::TIMEOUT_SEC + 5
class Foo
  TIMEOUT = 10
end

class Bar < Foo
  TIMEOUT = self::TIMEOUT + 10
end

puts Bar::TIMEOUT # 20

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it can be even shorter

TIMEOUT = TIMEOUT + 5

or

TIMEOUT += 5

but the visual of the code, especially the last one, looks like a constant reassignment. (It's not, though)
So my code is... a bit redundant but I'd like to use the redundant form here.


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