From fb4e16e9b2f1c9a09a6ed3c5cc31258b025efe8c Mon Sep 17 00:00:00 2001 From: youdie006 Date: Tue, 15 Sep 2026 09:55:42 +0900 Subject: [PATCH 1/2] Match absolute paths in the irb_require already-loaded check $LOADED_FEATURES holds absolute paths for anything the real require loaded, so anchoring the check with \A made it unable to match them. require 'x' followed by irb_require 'x' re-evaluates x.rb in the session. Anchor on a path boundary instead, which still rejects the foo/foo2 substring match #1253 was fixing. --- lib/irb/command/load.rb | 2 +- test/irb/test_command.rb | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/irb/command/load.rb b/lib/irb/command/load.rb index 36c6dbbad..983eeba61 100644 --- a/lib/irb/command/load.rb +++ b/lib/irb/command/load.rb @@ -45,7 +45,7 @@ def execute(arg) def execute_internal(file_name = nil) raise_cmd_argument_error unless file_name - rex = Regexp.new("\\A#{Regexp.escape(file_name)}(?:\\.o|\\.rb)?\\z") + rex = Regexp.new("(?:\\A|/)#{Regexp.escape(file_name)}(?:\\.o|\\.rb)?\\z") return false if $".find{|f| f =~ rex} case file_name diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb index 22b7c857c..68c25109f 100644 --- a/test/irb/test_command.rb +++ b/test/irb/test_command.rb @@ -473,6 +473,26 @@ def test_irb_require_file_matches_exact_name assert_match(/foo_loaded/, out) assert_match(/foo2_loaded/, out) end + + def test_irb_require_skips_file_already_loaded_by_require + File.write("#{@tmpdir}/irb_require_probe.rb", "$irb_require_probe_count = ($irb_require_probe_count || 0) + 1\n") + File.write("#{@tmpdir}/probe.rb", "'probe_loaded'\n") + File.write("#{@tmpdir}/irb_require.rb", "'prefix_loaded'\n") + + out, err = execute_lines( + "$LOAD_PATH.unshift '#{@tmpdir}'\n", + "require 'irb_require_probe'\n", + "irb_require 'irb_require_probe'\n", + "$irb_require_probe_count\n", + "irb_require 'probe'\n", + "irb_require 'irb_require'\n", + ) + + assert_empty(err) + assert_match(/=> 1\n/, out) + assert_match(/probe_loaded/, out) + assert_match(/prefix_loaded/, out) + end end class WorkspaceCommandTestCase < CommandTestCase From 74e609f90160636c8dd7bd5def21b768e7135fa3 Mon Sep 17 00:00:00 2001 From: youdie006 Date: Tue, 15 Sep 2026 10:06:26 +0900 Subject: [PATCH 2/2] Initialize the counter before requiring in the new test The probe file read an uninitialized global, which warns on stderr under -w and tripped the test's own assert_empty(err) on the CI rows that enable warnings. --- test/irb/test_command.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb index 68c25109f..73905e66c 100644 --- a/test/irb/test_command.rb +++ b/test/irb/test_command.rb @@ -475,12 +475,13 @@ def test_irb_require_file_matches_exact_name end def test_irb_require_skips_file_already_loaded_by_require - File.write("#{@tmpdir}/irb_require_probe.rb", "$irb_require_probe_count = ($irb_require_probe_count || 0) + 1\n") + File.write("#{@tmpdir}/irb_require_probe.rb", "$irb_require_probe_count += 1\n") File.write("#{@tmpdir}/probe.rb", "'probe_loaded'\n") File.write("#{@tmpdir}/irb_require.rb", "'prefix_loaded'\n") out, err = execute_lines( "$LOAD_PATH.unshift '#{@tmpdir}'\n", + "$irb_require_probe_count = 0\n", "require 'irb_require_probe'\n", "irb_require 'irb_require_probe'\n", "$irb_require_probe_count\n",