irb 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -11
  3. data/Rakefile +10 -0
  4. data/irb.gemspec +1 -1
  5. data/lib/irb/cmd/nop.rb +1 -1
  6. data/lib/irb/color.rb +2 -2
  7. data/lib/irb/command/backtrace.rb +2 -6
  8. data/lib/irb/command/base.rb +7 -9
  9. data/lib/irb/command/break.rb +2 -6
  10. data/lib/irb/command/catch.rb +2 -6
  11. data/lib/irb/command/chws.rb +11 -5
  12. data/lib/irb/command/context.rb +16 -0
  13. data/lib/irb/command/continue.rb +2 -2
  14. data/lib/irb/command/debug.rb +8 -1
  15. data/lib/irb/command/delete.rb +2 -2
  16. data/lib/irb/command/disable_irb.rb +19 -0
  17. data/lib/irb/command/edit.rb +6 -13
  18. data/lib/irb/command/exit.rb +1 -3
  19. data/lib/irb/command/finish.rb +2 -2
  20. data/lib/irb/command/force_exit.rb +1 -3
  21. data/lib/irb/command/help.rb +8 -17
  22. data/lib/irb/command/history.rb +4 -6
  23. data/lib/irb/command/info.rb +2 -6
  24. data/lib/irb/command/internal_helpers.rb +27 -0
  25. data/lib/irb/command/irb_info.rb +2 -2
  26. data/lib/irb/command/load.rb +20 -3
  27. data/lib/irb/command/ls.rb +20 -10
  28. data/lib/irb/command/measure.rb +12 -6
  29. data/lib/irb/command/next.rb +2 -2
  30. data/lib/irb/command/pushws.rb +10 -5
  31. data/lib/irb/command/show_doc.rb +9 -18
  32. data/lib/irb/command/show_source.rb +5 -12
  33. data/lib/irb/command/step.rb +2 -2
  34. data/lib/irb/command/subirb.rb +28 -12
  35. data/lib/irb/command/whereami.rb +1 -1
  36. data/lib/irb/command.rb +8 -303
  37. data/lib/irb/completion.rb +16 -5
  38. data/lib/irb/context.rb +21 -19
  39. data/lib/irb/default_commands.rb +260 -0
  40. data/lib/irb/ext/change-ws.rb +3 -5
  41. data/lib/irb/ext/multi-irb.rb +4 -4
  42. data/lib/irb/ext/workspaces.rb +3 -4
  43. data/lib/irb/help.rb +1 -1
  44. data/lib/irb/helper_method/base.rb +16 -0
  45. data/lib/irb/helper_method/conf.rb +11 -0
  46. data/lib/irb/helper_method.rb +29 -0
  47. data/lib/irb/history.rb +6 -3
  48. data/lib/irb/init.rb +60 -44
  49. data/lib/irb/input-method.rb +18 -10
  50. data/lib/irb/lc/error.rb +0 -5
  51. data/lib/irb/lc/ja/error.rb +0 -5
  52. data/lib/irb/lc/ja/help-message +10 -0
  53. data/lib/irb/statement.rb +5 -27
  54. data/lib/irb/version.rb +2 -2
  55. data/lib/irb/workspace.rb +18 -2
  56. data/lib/irb.rb +675 -624
  57. metadata +12 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ef257bd1b4917c3af8f4e1c372cb7c489cd16844df518e352c0bff74c77b4fc
4
- data.tar.gz: e9cd328330de9c415b93f680228ff79c3a798c481fe657bc48f7d7305470462c
3
+ metadata.gz: e4425b668e9f62b7535ef0db6b790b8e15a0ca62d4b81461d758c645c6043496
4
+ data.tar.gz: 36977d4a243c9acbc057729ff7bd6ea2432f8cfdb4013e7e4f2c05bebef26c70
5
5
  SHA512:
6
- metadata.gz: 78b5b33588812cda49274b45e7b905cec8cb9e6b0ed71be66a644680db5ac96a19e276952425ec54a05d2ce3e8cf99b69eb7964e310770e155ced4f51501b088
7
- data.tar.gz: 68ae7b61704a3356a14d526bdf058306c9ef158d8442030779b9256a59bee2929e1bab1fdf394f39bda09479b47430ca1de94c57c7b23017affec1400975e03a
6
+ metadata.gz: 804b6fa04f60f7ecc3bf98a9aa818fd8a0e177528c455ac46e853683463176b3eb651eb81e079b70870d2c4f55ab99d4292f10563f42b4c50d697e8e9684b810
7
+ data.tar.gz: 0f554e6950eda72508cf3af5eb4c446fc0584eec20c843cbf7ae653698b233add55251028dcf7a4991df5dfdfb90956589b728d727d4deb9e64cfe524349aab5
data/README.md CHANGED
@@ -351,21 +351,13 @@ irb(main):002> a.first. # Completes Integer methods
351
351
 
352
352
  ## Documentation
353
353
 
354
- https://docs.ruby-lang.org/en/master/IRB.html
354
+ https://ruby.github.io/irb/
355
355
 
356
356
  ## Extending IRB
357
357
 
358
- IRB is currently going through some refactoring to bring in some cool improvements and make things more flexible for developers.
359
- We know that in the past, due to a lack of public APIs and documentation, many of you have had to use IRB's private APIs
360
- and components to extend it. We also know that changes can be a bit annoying and might mess with your current setup.
358
+ IRB `v1.13.0` and later versions allows users/libraries to extend its functionality through official APIs.
361
359
 
362
- We're sorry if this causes a bit of a scramble. We're working hard to make IRB better and your input is super important to us.
363
- If you've been using private APIs or components in your projects, we'd love to hear about your use cases. Please feel free to file a new issue. Your feedback will be a massive help in guiding us on how to design and prioritize the development of official APIs in the future.
364
-
365
- Right now, we've got command extension APIs on the drawing board, as you can see in [#513](https://github.com/ruby/irb/issues/513).
366
- We've also got a prototype for helper method extension APIs in the works, as shown in [#588](https://github.com/ruby/irb/issues/588).
367
-
368
- We really appreciate your understanding and patience during this transition. We're pretty excited about the improvements these changes will bring to the IRB ecosystem and we hope you are too!
360
+ For more information, please visit [EXTEND_IRB.md](./EXTEND_IRB.md).
369
361
 
370
362
  ## Development
371
363
 
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require "rdoc/task"
3
4
 
4
5
  Rake::TestTask.new(:test) do |t|
5
6
  t.libs << "test" << "test/lib"
@@ -42,3 +43,12 @@ Rake::TestTask.new(:test_yamatanooroti) do |t|
42
43
  end
43
44
 
44
45
  task :default => :test
46
+
47
+ RDoc::Task.new do |rdoc|
48
+ rdoc.title = "IRB"
49
+ rdoc.rdoc_files.include("*.md", "lib/**/*.rb")
50
+ rdoc.rdoc_files.exclude("lib/irb/xmp.rb")
51
+ rdoc.rdoc_dir = "docs"
52
+ rdoc.main = "README.md"
53
+ rdoc.options.push("--copy-files", "LICENSE.txt")
54
+ end
data/irb.gemspec CHANGED
@@ -42,5 +42,5 @@ Gem::Specification.new do |spec|
42
42
  spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
43
43
 
44
44
  spec.add_dependency "reline", ">= 0.4.2"
45
- spec.add_dependency "rdoc"
45
+ spec.add_dependency "rdoc", ">= 4.0.0"
46
46
  end
data/lib/irb/cmd/nop.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # This file is just a placeholder for backward-compatibility.
4
- # Please require 'irb' and inheirt your command from `IRB::Command::Base` instead.
4
+ # Please require 'irb' and inherit your command from `IRB::Command::Base` instead.
data/lib/irb/color.rb CHANGED
@@ -79,12 +79,12 @@ module IRB # :nodoc:
79
79
 
80
80
  class << self
81
81
  def colorable?
82
- supported = $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
82
+ supported = $stdout.tty? && (/mswin|mingw/.match?(RUBY_PLATFORM) || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
83
83
 
84
84
  # because ruby/debug also uses irb's color module selectively,
85
85
  # irb won't be activated in that case.
86
86
  if IRB.respond_to?(:conf)
87
- supported && IRB.conf.fetch(:USE_COLORIZE, true)
87
+ supported && !!IRB.conf.fetch(:USE_COLORIZE, true)
88
88
  else
89
89
  supported
90
90
  end
@@ -7,12 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Backtrace < DebugCommand
10
- def self.transform_args(args)
11
- args&.dump
12
- end
13
-
14
- def execute(*args)
15
- super(pre_cmds: ["backtrace", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "backtrace #{arg}")
16
12
  end
17
13
  end
18
14
  end
@@ -10,6 +10,10 @@ module IRB
10
10
  module Command
11
11
  class CommandArgumentError < StandardError; end
12
12
 
13
+ def self.extract_ruby_args(*args, **kwargs)
14
+ throw :EXTRACT_RUBY_ARGS, [args, kwargs]
15
+ end
16
+
13
17
  class Base
14
18
  class << self
15
19
  def category(category = nil)
@@ -29,19 +33,13 @@ module IRB
29
33
 
30
34
  private
31
35
 
32
- def string_literal?(args)
33
- sexp = Ripper.sexp(args)
34
- sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
35
- end
36
-
37
36
  def highlight(text)
38
37
  Color.colorize(text, [:BOLD, :BLUE])
39
38
  end
40
39
  end
41
40
 
42
- def self.execute(irb_context, *opts, **kwargs, &block)
43
- command = new(irb_context)
44
- command.execute(*opts, **kwargs, &block)
41
+ def self.execute(irb_context, arg)
42
+ new(irb_context).execute(arg)
45
43
  rescue CommandArgumentError => e
46
44
  puts e.message
47
45
  end
@@ -52,7 +50,7 @@ module IRB
52
50
 
53
51
  attr_reader :irb_context
54
52
 
55
- def execute(*opts)
53
+ def execute(arg)
56
54
  #nop
57
55
  end
58
56
  end
@@ -7,12 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Break < DebugCommand
10
- def self.transform_args(args)
11
- args&.dump
12
- end
13
-
14
- def execute(args = nil)
15
- super(pre_cmds: "break #{args}")
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "break #{arg}")
16
12
  end
17
13
  end
18
14
  end
@@ -7,12 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Catch < DebugCommand
10
- def self.transform_args(args)
11
- args&.dump
12
- end
13
-
14
- def execute(*args)
15
- super(pre_cmds: ["catch", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "catch #{arg}")
16
12
  end
17
13
  end
18
14
  end
@@ -14,8 +14,8 @@ module IRB
14
14
  category "Workspace"
15
15
  description "Show the current workspace."
16
16
 
17
- def execute(*obj)
18
- irb_context.main
17
+ def execute(_arg)
18
+ puts "Current workspace: #{irb_context.main}"
19
19
  end
20
20
  end
21
21
 
@@ -23,9 +23,15 @@ module IRB
23
23
  category "Workspace"
24
24
  description "Change the current workspace to an object."
25
25
 
26
- def execute(*obj)
27
- irb_context.change_workspace(*obj)
28
- irb_context.main
26
+ def execute(arg)
27
+ if arg.empty?
28
+ irb_context.change_workspace
29
+ else
30
+ obj = eval(arg, irb_context.workspace.binding)
31
+ irb_context.change_workspace(obj)
32
+ end
33
+
34
+ puts "Current workspace: #{irb_context.main}"
29
35
  end
30
36
  end
31
37
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class Context < Base
6
+ category "IRB"
7
+ description "Displays current configuration."
8
+
9
+ def execute(_arg)
10
+ # This command just displays the configuration.
11
+ # Modifying the configuration is achieved by sending a message to IRB.conf.
12
+ Pager.page_content(IRB.CurrentContext.inspect)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -7,8 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Continue < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["continue", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "continue #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -13,7 +13,14 @@ module IRB
13
13
  binding.method(:irb).source_location.first,
14
14
  ].map { |file| /\A#{Regexp.escape(file)}:\d+:in (`|'Binding#)irb'\z/ }
15
15
 
16
- def execute(pre_cmds: nil, do_cmds: nil)
16
+ def execute(_arg)
17
+ execute_debug_command
18
+ end
19
+
20
+ def execute_debug_command(pre_cmds: nil, do_cmds: nil)
21
+ pre_cmds = pre_cmds&.rstrip
22
+ do_cmds = do_cmds&.rstrip
23
+
17
24
  if irb_context.with_debugger
18
25
  # If IRB is already running with a debug session, throw the command and IRB.debug_readline will pass it to the debugger.
19
26
  if cmd = pre_cmds || do_cmds
@@ -7,8 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Delete < DebugCommand
10
- def execute(*args)
11
- super(pre_cmds: ["delete", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "delete #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ # :stopdoc:
5
+
6
+ module Command
7
+ class DisableIrb < Base
8
+ category "IRB"
9
+ description "Disable binding.irb."
10
+
11
+ def execute(*)
12
+ ::Binding.define_method(:irb) {}
13
+ IRB.irb_exit
14
+ end
15
+ end
16
+ end
17
+
18
+ # :startdoc:
19
+ end
@@ -1,5 +1,6 @@
1
1
  require 'shellwords'
2
2
 
3
+ require_relative "../color"
3
4
  require_relative "../source_finder"
4
5
 
5
6
  module IRB
@@ -7,6 +8,8 @@ module IRB
7
8
 
8
9
  module Command
9
10
  class Edit < Base
11
+ include RubyArgsExtractor
12
+
10
13
  category "Misc"
11
14
  description 'Open a file or source location.'
12
15
  help_message <<~HELP_MESSAGE
@@ -26,19 +29,9 @@ module IRB
26
29
  edit Foo#bar
27
30
  HELP_MESSAGE
28
31
 
29
- class << self
30
- def transform_args(args)
31
- # Return a string literal as is for backward compatibility
32
- if args.nil? || args.empty? || string_literal?(args)
33
- args
34
- else # Otherwise, consider the input as a String for convenience
35
- args.strip.dump
36
- end
37
- end
38
- end
39
-
40
- def execute(*args)
41
- path = args.first
32
+ def execute(arg)
33
+ # Accept string literal for backward compatibility
34
+ path = unwrap_string_literal(arg)
42
35
 
43
36
  if path.nil?
44
37
  path = @irb_context.irb_path
@@ -8,10 +8,8 @@ module IRB
8
8
  category "IRB"
9
9
  description "Exit the current irb session."
10
10
 
11
- def execute(*)
11
+ def execute(_arg)
12
12
  IRB.irb_exit
13
- rescue UncaughtThrowError
14
- Kernel.exit
15
13
  end
16
14
  end
17
15
  end
@@ -7,8 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Finish < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["finish", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "finish #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -8,10 +8,8 @@ module IRB
8
8
  category "IRB"
9
9
  description "Exit the current process."
10
10
 
11
- def execute(*)
11
+ def execute(_arg)
12
12
  throw :IRB_EXIT, true
13
- rescue UncaughtThrowError
14
- Kernel.exit!
15
13
  end
16
14
  end
17
15
  end
@@ -6,27 +6,16 @@ module IRB
6
6
  category "Help"
7
7
  description "List all available commands. Use `help <command>` to get information about a specific command."
8
8
 
9
- class << self
10
- def transform_args(args)
11
- # Return a string literal as is for backward compatibility
12
- if args.empty? || string_literal?(args)
13
- args
14
- else # Otherwise, consider the input as a String for convenience
15
- args.strip.dump
16
- end
17
- end
18
- end
19
-
20
- def execute(command_name = nil)
9
+ def execute(command_name)
21
10
  content =
22
- if command_name
23
- if command_class = ExtendCommandBundle.load_command(command_name)
11
+ if command_name.empty?
12
+ help_message
13
+ else
14
+ if command_class = Command.load_command(command_name)
24
15
  command_class.help_message || command_class.description
25
16
  else
26
17
  "Can't find command `#{command_name}`. Please check the command name and try again.\n\n"
27
18
  end
28
- else
29
- help_message
30
19
  end
31
20
  Pager.page_content(content)
32
21
  end
@@ -34,8 +23,10 @@ module IRB
34
23
  private
35
24
 
36
25
  def help_message
37
- commands_info = IRB::ExtendCommandBundle.all_commands_info
26
+ commands_info = IRB::Command.all_commands_info
27
+ helper_methods_info = IRB::HelperMethod.all_helper_methods_info
38
28
  commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
29
+ commands_grouped_by_categories["Helper methods"] = helper_methods_info
39
30
 
40
31
  user_aliases = irb_context.instance_variable_get(:@user_aliases)
41
32
 
@@ -12,14 +12,12 @@ module IRB
12
12
  category "IRB"
13
13
  description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
14
14
 
15
- def self.transform_args(args)
16
- match = args&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/)
17
- return unless match
15
+ def execute(arg)
18
16
 
19
- "grep: #{Regexp.new(match[:grep]).inspect}"
20
- end
17
+ if (match = arg&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/))
18
+ grep = Regexp.new(match[:grep])
19
+ end
21
20
 
22
- def execute(grep: nil)
23
21
  formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
24
22
  next if grep && !input.match?(grep)
25
23
 
@@ -7,12 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Info < DebugCommand
10
- def self.transform_args(args)
11
- args&.dump
12
- end
13
-
14
- def execute(*args)
15
- super(pre_cmds: ["info", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(pre_cmds: "info #{arg}")
16
12
  end
17
13
  end
18
14
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ # Internal use only, for default command's backward compatibility.
6
+ module RubyArgsExtractor # :nodoc:
7
+ def unwrap_string_literal(str)
8
+ return if str.empty?
9
+
10
+ sexp = Ripper.sexp(str)
11
+ if sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
12
+ @irb_context.workspace.binding.eval(str).to_s
13
+ else
14
+ str
15
+ end
16
+ end
17
+
18
+ def ruby_args(arg)
19
+ # Use throw and catch to handle arg that includes `;`
20
+ # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
21
+ catch(:EXTRACT_RUBY_ARGS) do
22
+ @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
23
+ end || [[], {}]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -8,12 +8,12 @@ module IRB
8
8
  category "IRB"
9
9
  description "Show information about IRB."
10
10
 
11
- def execute
11
+ def execute(_arg)
12
12
  str = "Ruby version: #{RUBY_VERSION}\n"
13
13
  str += "IRB version: #{IRB.version}\n"
14
14
  str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
15
15
  str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n"
16
- rc_files = IRB.rc_files.select { |rc| File.exist?(rc) }
16
+ rc_files = IRB.irbrc_files
17
17
  str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any?
18
18
  str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
19
19
  str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
@@ -10,6 +10,7 @@ module IRB
10
10
 
11
11
  module Command
12
12
  class LoaderCommand < Base
13
+ include RubyArgsExtractor
13
14
  include IrbLoader
14
15
 
15
16
  def raise_cmd_argument_error
@@ -21,7 +22,12 @@ module IRB
21
22
  category "IRB"
22
23
  description "Load a Ruby file."
23
24
 
24
- def execute(file_name = nil, priv = nil)
25
+ def execute(arg)
26
+ args, kwargs = ruby_args(arg)
27
+ execute_internal(*args, **kwargs)
28
+ end
29
+
30
+ def execute_internal(file_name = nil, priv = nil)
25
31
  raise_cmd_argument_error unless file_name
26
32
  irb_load(file_name, priv)
27
33
  end
@@ -30,7 +36,13 @@ module IRB
30
36
  class Require < LoaderCommand
31
37
  category "IRB"
32
38
  description "Require a Ruby file."
33
- def execute(file_name = nil)
39
+
40
+ def execute(arg)
41
+ args, kwargs = ruby_args(arg)
42
+ execute_internal(*args, **kwargs)
43
+ end
44
+
45
+ def execute_internal(file_name = nil)
34
46
  raise_cmd_argument_error unless file_name
35
47
 
36
48
  rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
@@ -63,7 +75,12 @@ module IRB
63
75
  category "IRB"
64
76
  description "Loads a given file in the current session."
65
77
 
66
- def execute(file_name = nil)
78
+ def execute(arg)
79
+ args, kwargs = ruby_args(arg)
80
+ execute_internal(*args, **kwargs)
81
+ end
82
+
83
+ def execute_internal(file_name = nil)
67
84
  raise_cmd_argument_error unless file_name
68
85
 
69
86
  source_file(file_name)
@@ -11,6 +11,8 @@ module IRB
11
11
 
12
12
  module Command
13
13
  class Ls < Base
14
+ include RubyArgsExtractor
15
+
14
16
  category "Context"
15
17
  description "Show methods, constants, and variables."
16
18
 
@@ -20,27 +22,35 @@ module IRB
20
22
  -g [query] Filter the output with a query.
21
23
  HELP_MESSAGE
22
24
 
23
- def self.transform_args(args)
24
- if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
25
- args = match[:args]
26
- "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
25
+ def execute(arg)
26
+ if match = arg.match(/\A(?<target>.+\s|)(-g|-G)\s+(?<grep>.+)$/)
27
+ if match[:target].empty?
28
+ use_main = true
29
+ else
30
+ obj = @irb_context.workspace.binding.eval(match[:target])
31
+ end
32
+ grep = Regexp.new(match[:grep])
27
33
  else
28
- args
34
+ args, kwargs = ruby_args(arg)
35
+ use_main = args.empty?
36
+ obj = args.first
37
+ grep = kwargs[:grep]
38
+ end
39
+
40
+ if use_main
41
+ obj = irb_context.workspace.main
42
+ locals = irb_context.workspace.binding.local_variables
29
43
  end
30
- end
31
44
 
32
- def execute(*arg, grep: nil)
33
45
  o = Output.new(grep: grep)
34
46
 
35
- obj = arg.empty? ? irb_context.workspace.main : arg.first
36
- locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
37
47
  klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
38
48
 
39
49
  o.dump("constants", obj.constants) if obj.respond_to?(:constants)
40
50
  dump_methods(o, klass, obj)
41
51
  o.dump("instance variables", obj.instance_variables)
42
52
  o.dump("class variables", klass.class_variables)
43
- o.dump("locals", locals)
53
+ o.dump("locals", locals) if locals
44
54
  o.print_result
45
55
  end
46
56
 
@@ -3,6 +3,8 @@ module IRB
3
3
 
4
4
  module Command
5
5
  class Measure < Base
6
+ include RubyArgsExtractor
7
+
6
8
  category "Misc"
7
9
  description "`measure` enables the mode to measure processing time. `measure :off` disables it."
8
10
 
@@ -10,15 +12,19 @@ module IRB
10
12
  super(*args)
11
13
  end
12
14
 
13
- def execute(type = nil, arg = nil)
14
- # Please check IRB.init_config in lib/irb/init.rb that sets
15
- # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
16
- # "measure :time" (abbreviated as "measure") and "measure :stackprof".
17
-
18
- if block_given?
15
+ def execute(arg)
16
+ if arg&.match?(/^do$|^do[^\w]|^\{/)
19
17
  warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.'
20
18
  return
21
19
  end
20
+ args, kwargs = ruby_args(arg)
21
+ execute_internal(*args, **kwargs)
22
+ end
23
+
24
+ def execute_internal(type = nil, arg = nil)
25
+ # Please check IRB.init_config in lib/irb/init.rb that sets
26
+ # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
27
+ # "measure :time" (abbreviated as "measure") and "measure :stackprof".
22
28
 
23
29
  case type
24
30
  when :off
@@ -7,8 +7,8 @@ module IRB
7
7
 
8
8
  module Command
9
9
  class Next < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["next", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "next #{arg}")
12
12
  end
13
13
  end
14
14
  end