[ruby/irb] Don't show 'Maybe IRB bug!' in show_source and ls command

(https://github.com/ruby/irb/pull/1039)

https://github.com/ruby/irb/commit/9eb14a3a0b
This commit is contained in:
tomoya ishida 2024-12-04 06:55:27 +09:00 committed by git
parent 3a90663776
commit e539342f65
4 changed files with 51 additions and 14 deletions

View File

@ -11,7 +11,7 @@ module IRB
module Command module Command
class Ls < Base class Ls < Base
include RubyArgsExtractor class EvaluationError < StandardError; end
category "Context" category "Context"
description "Show methods, constants, and variables." description "Show methods, constants, and variables."
@ -22,24 +22,35 @@ module IRB
-g [query] Filter the output with a query. -g [query] Filter the output with a query.
HELP_MESSAGE HELP_MESSAGE
def evaluate(code)
@irb_context.workspace.binding.eval(code)
rescue Exception => e
puts "#{e.class}: #{e.message}"
raise EvaluationError
end
def execute(arg) def execute(arg)
if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/) if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
if match[:target].empty? target = match[:target]
use_main = true
else
obj = @irb_context.workspace.binding.eval(match[:target])
end
grep = Regexp.new(match[:grep]) grep = Regexp.new(match[:grep])
elsif match = arg.match(/\A((?<target>.+),|)\s*grep:(?<grep>.+)/)
# Legacy style `ls obj, grep: /regexp/`
# Evaluation order should be eval(target) then eval(grep)
target = match[:target] || ''
grep_regexp_code = match[:grep]
else else
args, kwargs = ruby_args(arg) target = arg.strip
use_main = args.empty?
obj = args.first
grep = kwargs[:grep]
end end
if use_main if target.empty?
obj = irb_context.workspace.main obj = irb_context.workspace.main
locals = irb_context.workspace.binding.local_variables locals = irb_context.workspace.binding.local_variables
else
obj = evaluate(target)
end
if grep_regexp_code
grep = evaluate(grep_regexp_code)
end end
o = Output.new(grep: grep) o = Output.new(grep: grep)
@ -52,6 +63,7 @@ module IRB
o.dump("class variables", klass.class_variables) o.dump("class variables", klass.class_variables)
o.dump("locals", locals) if locals o.dump("locals", locals) if locals
o.print_result o.print_result
rescue EvaluationError
end end
def dump_methods(o, klass, obj) def dump_methods(o, klass, obj)

View File

@ -125,9 +125,8 @@ module IRB
end end
def eval_receiver_or_owner(code) def eval_receiver_or_owner(code)
context_binding = @irb_context.workspace.binding @irb_context.workspace.binding.eval(code)
eval(code, context_binding) rescue Exception
rescue NameError
raise EvaluationError raise EvaluationError
end end

View File

@ -65,6 +65,19 @@ module TestIRB
assert_match(%r[Couldn't locate a definition for Foo], out) assert_match(%r[Couldn't locate a definition for Foo], out)
end end
def test_show_source_with_eval_error
write_ruby <<~'RUBY'
binding.irb
RUBY
out = run_ruby_file do
type "show_source raise(Exception).itself"
type "exit"
end
assert_match(%r[Couldn't locate a definition for raise\(Exception\)\.itself], out)
end
def test_show_source_string def test_show_source_string
write_ruby <<~'RUBY' write_ruby <<~'RUBY'
binding.irb binding.irb

View File

@ -742,6 +742,19 @@ module TestIRB
end end
end end
def test_ls_with_eval_error
[
"ls raise(Exception,'foo')\n",
"ls raise(Exception,'foo'), grep: /./\n",
"ls Integer, grep: raise(Exception,'foo')\n",
].each do |line|
out, err = execute_lines(line)
assert_empty err
assert_match(/Exception: foo/, out)
assert_not_match(/Maybe IRB bug!/, out)
end
end
def test_ls_with_no_singleton_class def test_ls_with_no_singleton_class
out, err = execute_lines( out, err = execute_lines(
"ls 42", "ls 42",