Skip to content

Commit fa0fbb7

Browse files
authored
Avoid calling private methods on the main object (#498)
When the main object is frozen, `IRB` wraps a `SimpleDelegator` around it. But because `SimpleDelegator` doesn't delegate private methods, methods like `require_relative` or `const_get` would cause error, which are needed for lazily loading commands. This commit works around this limitation by avoiding those private method calls when setting up command execution.
1 parent bfe9915 commit fa0fbb7

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

lib/irb/extend-command.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ def self.def_extend_command(cmd_name, cmd_class, load_file = nil, *aliases)
259259
kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
260260
line = __LINE__; eval %[
261261
def #{cmd_name}(*opts#{kwargs}, &b)
262-
require_relative "#{load_file}"
263-
arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
262+
Kernel.require_relative "#{load_file}"
263+
arity = ::IRB::ExtendCommand::#{cmd_class}.instance_method(:execute).arity
264264
args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
265265
args << "*opts#{kwargs}" if arity < 0
266266
args << "&block"
@@ -269,7 +269,7 @@ def #{cmd_name}(*opts#{kwargs}, &b)
269269
unless singleton_class.class_variable_defined?(:@@#{cmd_name}_)
270270
singleton_class.class_variable_set(:@@#{cmd_name}_, true)
271271
def self.#{cmd_name}_(\#{args})
272-
ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
272+
::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, \#{args})
273273
end
274274
end
275275
], nil, __FILE__, line
@@ -279,7 +279,7 @@ def self.#{cmd_name}_(\#{args})
279279
else
280280
line = __LINE__; eval %[
281281
def #{cmd_name}(*opts, &b)
282-
ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
282+
::IRB::ExtendCommand::#{cmd_class}.execute(irb_context, *opts, &b)
283283
end
284284
], nil, __FILE__, line
285285
end

test/irb/test_cmd.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ def execute_lines(*lines, conf: {}, main: self, irb_path: nil)
4949
end
5050
end
5151

52+
class FrozenObjectTest < CommandTestCase
53+
def test_calling_command_on_a_frozen_main
54+
main = Object.new.freeze
55+
56+
out, err = execute_lines(
57+
"irb_info",
58+
main: main
59+
)
60+
assert_empty err
61+
assert_match(/RUBY_PLATFORM/, out)
62+
end
63+
end
64+
5265
class CommnadAliasTest < CommandTestCase
5366
def test_vars_with_aliases
5467
@foo = "foo"

0 commit comments

Comments
 (0)