[ruby/irb] Use flag instead of caller for debug's binding.irb

check
(https://github.com/ruby/irb/pull/947)

https://github.com/ruby/irb/commit/4a4d7a4279
This commit is contained in:
Stan Lo 2024-05-04 11:22:14 +08:00 committed by git
parent cf74ff714a
commit fb2ea7084f
4 changed files with 26 additions and 18 deletions

View File

@ -931,8 +931,11 @@ module IRB
# The lexer used by this irb session
attr_accessor :scanner
attr_reader :from_binding
# Creates a new irb session
def initialize(workspace = nil, input_method = nil)
def initialize(workspace = nil, input_method = nil, from_binding: false)
@from_binding = from_binding
@context = Context.new(self, workspace, input_method)
@context.workspace.load_helper_methods_to_main
@signal_status = :IN_IRB
@ -1596,7 +1599,7 @@ class Binding
else
# If we're not in a debugger session, create a new IRB instance with the current
# workspace
binding_irb = IRB::Irb.new(workspace)
binding_irb = IRB::Irb.new(workspace, from_binding: true)
binding_irb.context.irb_path = irb_path
binding_irb.run(IRB.conf)
binding_irb.debug_break

View File

@ -8,11 +8,6 @@ module IRB
category "Debugging"
description "Start the debugger of debug.gem."
BINDING_IRB_FRAME_REGEXPS = [
'<internal:prelude>',
binding.method(:irb).source_location.first,
].map { |file| /\A#{Regexp.escape(file)}:\d+:in (`|'Binding#)irb'\z/ }
def execute(_arg)
execute_debug_command
end
@ -36,7 +31,7 @@ module IRB
# 3. Insert a debug breakpoint at `Irb#debug_break` with the intended command.
# 4. Exit the current Irb#run call via `throw :IRB_EXIT`.
# 5. `Irb#debug_break` will be called and trigger the breakpoint, which will run the intended command.
unless binding_irb?
unless irb_context.from_binding?
puts "Debugging commands are only available when IRB is started with binding.irb"
return
end
@ -60,16 +55,6 @@ module IRB
throw :IRB_EXIT
end
end
private
def binding_irb?
caller.any? do |frame|
BINDING_IRB_FRAME_REGEXPS.any? do |regexp|
frame.match?(regexp)
end
end
end
end
class DebugCommand < Debug

View File

@ -607,6 +607,10 @@ module IRB
nil
end
def from_binding?
@irb.from_binding
end
def evaluate_expression(code, line_no) # :nodoc:
result = nil
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?

View File

@ -67,6 +67,22 @@ module TestIRB
assert_match(/IRB is already running with a debug session/, output)
end
def test_debug_command_can_only_be_called_from_binding_irb
write_ruby <<~'ruby'
require "irb"
# trick test framework
puts "binding.irb"
IRB.start
ruby
output = run_ruby_file do
type "debug"
type "exit"
end
assert_include(output, "Debugging commands are only available when IRB is started with binding.irb")
end
def test_next
write_ruby <<~'ruby'
binding.irb