summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomoya ishida <tomoyapenguin@gmail.com>2024-12-04 06:55:27 +0900
committergit <svn-admin@ruby-lang.org>2024-12-03 21:55:33 +0000
commite539342f65e468fc7f926277eff61cb8b8a60622 (patch)
treef224d57b8e1c249f19d69db777046b0ac1078f98
parent3a90663776f94e4a617a4069d1d073cc1eca0526 (diff)
[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
-rw-r--r--lib/irb/command/ls.rb34
-rw-r--r--lib/irb/source_finder.rb5
-rw-r--r--test/irb/command/test_show_source.rb13
-rw-r--r--test/irb/test_command.rb13
4 files changed, 51 insertions, 14 deletions
diff --git a/lib/irb/command/ls.rb b/lib/irb/command/ls.rb
index cbd9998bc4..944efd7570 100644
--- a/lib/irb/command/ls.rb
+++ b/lib/irb/command/ls.rb
@@ -11,7 +11,7 @@ module IRB
module Command
class Ls < Base
- include RubyArgsExtractor
+ class EvaluationError < StandardError; end
category "Context"
description "Show methods, constants, and variables."
@@ -22,24 +22,35 @@ module IRB
-g [query] Filter the output with a query.
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)
if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
- if match[:target].empty?
- use_main = true
- else
- obj = @irb_context.workspace.binding.eval(match[:target])
- end
+ target = match[:target]
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
- args, kwargs = ruby_args(arg)
- use_main = args.empty?
- obj = args.first
- grep = kwargs[:grep]
+ target = arg.strip
end
- if use_main
+ if target.empty?
obj = irb_context.workspace.main
locals = irb_context.workspace.binding.local_variables
+ else
+ obj = evaluate(target)
+ end
+
+ if grep_regexp_code
+ grep = evaluate(grep_regexp_code)
end
o = Output.new(grep: grep)
@@ -52,6 +63,7 @@ module IRB
o.dump("class variables", klass.class_variables)
o.dump("locals", locals) if locals
o.print_result
+ rescue EvaluationError
end
def dump_methods(o, klass, obj)
diff --git a/lib/irb/source_finder.rb b/lib/irb/source_finder.rb
index c515da5702..6e1e58069f 100644
--- a/lib/irb/source_finder.rb
+++ b/lib/irb/source_finder.rb
@@ -125,9 +125,8 @@ module IRB
end
def eval_receiver_or_owner(code)
- context_binding = @irb_context.workspace.binding
- eval(code, context_binding)
- rescue NameError
+ @irb_context.workspace.binding.eval(code)
+ rescue Exception
raise EvaluationError
end
diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb
index d014c78fc4..a4227231e4 100644
--- a/test/irb/command/test_show_source.rb
+++ b/test/irb/command/test_show_source.rb
@@ -65,6 +65,19 @@ module TestIRB
assert_match(%r[Couldn't locate a definition for Foo], out)
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
write_ruby <<~'RUBY'
binding.irb
diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb
index 69931e3e4f..21e05752b9 100644
--- a/test/irb/test_command.rb
+++ b/test/irb/test_command.rb
@@ -742,6 +742,19 @@ module TestIRB
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
out, err = execute_lines(
"ls 42",