irb 1.4.2 → 1.6.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25f63261bbf06e8b1605b8a680e538dd90641ad2492c0bfb0f8e127f673e2793
4
- data.tar.gz: 9f113f6c97887e83f9d476dba5e4c0a5656d76cc554e1e818c94e8828b4051fa
3
+ metadata.gz: 7a14d4867e5744e554edbcd7e87f397bd01305fd2e5dca129bfa4d0a49abdd12
4
+ data.tar.gz: b6ed771b62fc49d60ac292a87cd5bafb2ec79b5715ec73bc816923fcb68de2ea
5
5
  SHA512:
6
- metadata.gz: 024d8e4dc13978bbae5ed3404e3ecff763da3fcc01e26c43d3e7e54822121bbc708de49c5a9c951a15c0ceee05a60cf282cbbd6ae6ec42960e9a8943a9217417
7
- data.tar.gz: 146edac46f0d81a01e120493e56eefa8d8b51143851718876617673bcbddf19b54e246d55541833101926e17186ce55b6484e2fb20e6f57735ee49ddfe0b6890
6
+ metadata.gz: 0acdbeae9c9aa9a83677a903ddf5006f82dc2dd4697d1e089ec360d0f77f049ebbaf3492b3ca5bda0a7c8814bac0e5ccde351e5a2d2c487170761d874204f02c
7
+ data.tar.gz: 4f92f7aadb2876a4d774ac52f27701cb8c723f400000a560f2452779b9562ad0d1a202b4534a52029662d0a2f910cdd816bdf43e275b800211c9ec062ae1241e
data/Gemfile CHANGED
@@ -11,4 +11,5 @@ group :development do
11
11
  gem "stackprof" if is_unix && !is_truffleruby
12
12
  gem "test-unit"
13
13
  gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
14
+ gem "debug", github: "ruby/debug"
14
15
  end
data/README.md CHANGED
@@ -40,6 +40,60 @@ irb(main):006:1> end
40
40
 
41
41
  The Readline extension module can be used with irb. Use of Readline is default if it's installed.
42
42
 
43
+ ## Commands
44
+
45
+ The following commands are available on IRB. You can get the same output from the `show_cmds` command.
46
+
47
+
48
+ ```
49
+ IRB
50
+ cwws Show the current workspace.
51
+ chws Change the current workspace to an object.
52
+ workspaces Show workspaces.
53
+ pushws Push an object to the workspace stack.
54
+ popws Pop a workspace from the workspace stack.
55
+ irb_load Load a Ruby file.
56
+ irb_require Require a Ruby file.
57
+ source Loads a given file in the current session.
58
+ irb Start a child IRB.
59
+ jobs List of current sessions.
60
+ fg Switches to the session of the given number.
61
+ kill Kills the session with the given number.
62
+ irb_info Show information about IRB.
63
+ show_cmds List all available commands and their description.
64
+
65
+ Debugging
66
+ debug Start the debugger of debug.gem.
67
+ break Start the debugger of debug.gem and run its `break` command.
68
+ catch Start the debugger of debug.gem and run its `catch` command.
69
+ next Start the debugger of debug.gem and run its `next` command.
70
+ delete Start the debugger of debug.gem and run its `delete` command.
71
+ step Start the debugger of debug.gem and run its `step` command.
72
+ continue Start the debugger of debug.gem and run its `continue` command.
73
+ finish Start the debugger of debug.gem and run its `finish` command.
74
+ backtrace Start the debugger of debug.gem and run its `backtrace` command.
75
+ info Start the debugger of debug.gem and run its `info` command.
76
+
77
+ Misc
78
+ edit Open a file with the editor command defined with `ENV["EDITOR"]`.
79
+ measure `measure` enables the mode to measure processing time. `measure :off` disables it.
80
+
81
+ Context
82
+ show_doc Enter the mode to look up RI documents.
83
+ ls Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output.
84
+ show_source Show the source code of a given method or constant.
85
+ whereami Show the source code around binding.irb again.
86
+ ```
87
+
88
+ ## Configuration
89
+
90
+ ### Environment Variables
91
+
92
+ - `NO_COLOR`: Assigning a value to it disables IRB's colorization.
93
+ - `IRB_USE_AUTOCOMPLETE`: Setting it to `false` disables IRB's autocompletion.
94
+ - `EDITOR`: Its value would be used to open files by the `edit` command.
95
+ - `IRBRC`: The file specified would be evaluated as IRB's rc-file.
96
+
43
97
  ## Documentation
44
98
 
45
99
  https://docs.ruby-lang.org/en/master/IRB.html
@@ -54,6 +108,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
54
108
 
55
109
  Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/irb.
56
110
 
111
+ ## Releasing
112
+
113
+ ```
114
+ rake release
115
+ gh release create vX.Y.Z --generate-notes
116
+ ```
117
+
57
118
  ## License
58
119
 
59
120
  The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
data/Rakefile CHANGED
@@ -8,6 +8,31 @@ Rake::TestTask.new(:test) do |t|
8
8
  t.test_files = FileList["test/irb/test_*.rb"]
9
9
  end
10
10
 
11
+ # To make sure they have been correctly setup for Ruby CI.
12
+ desc "Run each irb test file in isolation."
13
+ task :test_in_isolation do
14
+ failed = false
15
+
16
+ FileList["test/irb/test_*.rb"].each do |test_file|
17
+ ENV["TEST"] = test_file
18
+ begin
19
+ Rake::Task["test"].execute
20
+ rescue => e
21
+ failed = true
22
+ msg = "Test '#{test_file}' failed when being executed in isolation. Please make sure 'rake test TEST=#{test_file}' passes."
23
+ separation_line = '=' * msg.length
24
+
25
+ puts <<~MSG
26
+ #{separation_line}
27
+ #{msg}
28
+ #{separation_line}
29
+ MSG
30
+ end
31
+ end
32
+
33
+ fail "Some tests failed when being executed in isolation" if failed
34
+ end
35
+
11
36
  Rake::TestTask.new(:test_yamatanooroti) do |t|
12
37
  t.libs << 'test' << "test/lib"
13
38
  t.libs << 'lib'
data/irb.gemspec CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
35
  spec.require_paths = ["lib"]
36
36
 
37
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
37
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
38
38
 
39
39
  spec.add_dependency "reline", ">= 0.3.0"
40
40
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
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(" "))
16
+ end
17
+ end
18
+ end
19
+
20
+ # :startdoc:
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
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}")
16
+ end
17
+ end
18
+ end
19
+
20
+ # :startdoc:
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
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(" "))
16
+ end
17
+ end
18
+ end
19
+
20
+ # :startdoc:
21
+ end
data/lib/irb/cmd/chws.rb CHANGED
@@ -19,12 +19,18 @@ module IRB
19
19
  module ExtendCommand
20
20
 
21
21
  class CurrentWorkingWorkspace < Nop
22
+ category "IRB"
23
+ description "Show the current workspace."
24
+
22
25
  def execute(*obj)
23
26
  irb_context.main
24
27
  end
25
28
  end
26
29
 
27
30
  class ChangeWorkspace < Nop
31
+ category "IRB"
32
+ description "Change the current workspace to an object."
33
+
28
34
  def execute(*obj)
29
35
  irb_context.change_workspace(*obj)
30
36
  irb_context.main
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
9
+ class Continue < DebugCommand
10
+ def execute(*args)
11
+ super(do_cmds: ["continue", *args].join(" "))
12
+ end
13
+ end
14
+ end
15
+
16
+ # :startdoc:
17
+ end
@@ -0,0 +1,135 @@
1
+ require_relative "nop"
2
+
3
+ module IRB
4
+ # :stopdoc:
5
+
6
+ module ExtendCommand
7
+ class Debug < Nop
8
+ category "Debugging"
9
+ description "Start the debugger of debug.gem."
10
+
11
+ BINDING_IRB_FRAME_REGEXPS = [
12
+ '<internal:prelude>',
13
+ binding.method(:irb).source_location.first,
14
+ ].map { |file| /\A#{Regexp.escape(file)}:\d+:in `irb'\z/ }
15
+ IRB_DIR = File.expand_path('..', __dir__)
16
+
17
+ def execute(pre_cmds: nil, do_cmds: nil)
18
+ unless binding_irb?
19
+ puts "`debug` command is only available when IRB is started with binding.irb"
20
+ return
21
+ end
22
+
23
+ unless setup_debugger
24
+ puts <<~MSG
25
+ You need to install the debug gem before using this command.
26
+ If you use `bundle exec`, please add `gem "debug"` into your Gemfile.
27
+ MSG
28
+ return
29
+ end
30
+
31
+ options = { oneshot: true, hook_call: false }
32
+ if pre_cmds || do_cmds
33
+ options[:command] = ['irb', pre_cmds, do_cmds]
34
+ end
35
+ if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src])
36
+ options[:skip_src] = true
37
+ end
38
+
39
+ # To make debugger commands like `next` or `continue` work without asking
40
+ # the user to quit IRB after that, we need to exit IRB first and then hit
41
+ # a TracePoint on #debug_break.
42
+ file, lineno = IRB::Irb.instance_method(:debug_break).source_location
43
+ DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options)
44
+ # exit current Irb#run call
45
+ throw :IRB_EXIT
46
+ end
47
+
48
+ private
49
+
50
+ def binding_irb?
51
+ caller.any? do |frame|
52
+ BINDING_IRB_FRAME_REGEXPS.any? do |regexp|
53
+ frame.match?(regexp)
54
+ end
55
+ end
56
+ end
57
+
58
+ module SkipPathHelperForIRB
59
+ def skip_internal_path?(path)
60
+ # The latter can be removed once https://github.com/ruby/debug/issues/866 is resolved
61
+ super || path.match?(IRB_DIR) || path.match?('<internal:prelude>')
62
+ end
63
+ end
64
+
65
+ def setup_debugger
66
+ unless defined?(DEBUGGER__::SESSION)
67
+ begin
68
+ require "debug/session"
69
+ rescue LoadError # debug.gem is not written in Gemfile
70
+ return false unless load_bundled_debug_gem
71
+ end
72
+ DEBUGGER__.start(nonstop: true)
73
+ end
74
+
75
+ unless DEBUGGER__.respond_to?(:capture_frames_without_irb)
76
+ DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames)
77
+
78
+ def DEBUGGER__.capture_frames(*args)
79
+ frames = capture_frames_without_irb(*args)
80
+ frames.reject! do |frame|
81
+ frame.realpath&.start_with?(IRB_DIR) || frame.path == "<internal:prelude>"
82
+ end
83
+ frames
84
+ end
85
+
86
+ DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
87
+ end
88
+
89
+ true
90
+ end
91
+
92
+ # This is used when debug.gem is not written in Gemfile. Even if it's not
93
+ # installed by `bundle install`, debug.gem is installed by default because
94
+ # it's a bundled gem. This method tries to activate and load that.
95
+ def load_bundled_debug_gem
96
+ # Discover latest debug.gem under GEM_PATH
97
+ debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path|
98
+ File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/)
99
+ end.sort_by do |path|
100
+ Gem::Version.new(File.basename(path).delete_prefix('debug-'))
101
+ end.last
102
+ return false unless debug_gem
103
+
104
+ # Discover debug/debug.so under extensions for Ruby 3.2+
105
+ debug_so = Gem.paths.path.flat_map do |path|
106
+ Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}/debug/debug.so")
107
+ end.first
108
+
109
+ # Attempt to forcibly load the bundled gem
110
+ if debug_so
111
+ $LOAD_PATH << debug_so.delete_suffix('/debug/debug.so')
112
+ end
113
+ $LOAD_PATH << "#{debug_gem}/lib"
114
+ begin
115
+ require "debug/session"
116
+ puts "Loaded #{File.basename(debug_gem)}"
117
+ true
118
+ rescue LoadError
119
+ false
120
+ end
121
+ end
122
+ end
123
+
124
+ class DebugCommand < Debug
125
+ def self.category
126
+ "Debugging"
127
+ end
128
+
129
+ def self.description
130
+ command_name = self.name.split("::").last.downcase
131
+ "Start the debugger of debug.gem and run its `#{command_name}` command."
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
9
+ class Delete < DebugCommand
10
+ def execute(*args)
11
+ super(pre_cmds: ["delete", *args].join(" "))
12
+ end
13
+ end
14
+ end
15
+
16
+ # :startdoc:
17
+ end
@@ -0,0 +1,61 @@
1
+ require 'shellwords'
2
+ require_relative "nop"
3
+
4
+ module IRB
5
+ # :stopdoc:
6
+
7
+ module ExtendCommand
8
+ class Edit < Nop
9
+ category "Misc"
10
+ description 'Open a file with the editor command defined with `ENV["EDITOR"]`.'
11
+
12
+ class << self
13
+ def transform_args(args)
14
+ # Return a string literal as is for backward compatibility
15
+ if args.nil? || args.empty? || string_literal?(args)
16
+ args
17
+ else # Otherwise, consider the input as a String for convenience
18
+ args.strip.dump
19
+ end
20
+ end
21
+ end
22
+
23
+ def execute(*args)
24
+ path = args.first
25
+
26
+ if path.nil? && (irb_path = @irb_context.irb_path)
27
+ path = irb_path
28
+ end
29
+
30
+ if !File.exist?(path)
31
+ require_relative "show_source"
32
+
33
+ source =
34
+ begin
35
+ ShowSource.find_source(path, @irb_context)
36
+ rescue NameError
37
+ # if user enters a path that doesn't exist, it'll cause NameError when passed here because find_source would try to evaluate it as well
38
+ # in this case, we should just ignore the error
39
+ end
40
+
41
+ if source && File.exist?(source.file)
42
+ path = source.file
43
+ else
44
+ puts "Can not find file: #{path}"
45
+ return
46
+ end
47
+ end
48
+
49
+ if editor = ENV['EDITOR']
50
+ puts "command: '#{editor}'"
51
+ puts " path: #{path}"
52
+ system(*Shellwords.split(editor), path)
53
+ else
54
+ puts "Can not find editor setting: ENV['EDITOR']"
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ # :startdoc:
61
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "debug"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
9
+ class Finish < DebugCommand
10
+ def execute(*args)
11
+ super(do_cmds: ["finish", *args].join(" "))
12
+ end
13
+ end
14
+ end
15
+
16
+ # :startdoc:
17
+ end
data/lib/irb/cmd/help.rb CHANGED
@@ -16,6 +16,20 @@ module IRB
16
16
 
17
17
  module ExtendCommand
18
18
  class Help < Nop
19
+ class << self
20
+ def transform_args(args)
21
+ # Return a string literal as is for backward compatibility
22
+ if args.empty? || string_literal?(args)
23
+ args
24
+ else # Otherwise, consider the input as a String for convenience
25
+ args.strip.dump
26
+ end
27
+ end
28
+ end
29
+
30
+ category "Context"
31
+ description "Enter the mode to look up RI documents."
32
+
19
33
  def execute(*names)
20
34
  require 'rdoc/ri/driver'
21
35
  opts = RDoc::RI::Driver.process_args([])
data/lib/irb/cmd/info.rb CHANGED
@@ -1,31 +1,18 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
 
3
- require_relative "nop"
3
+ require_relative "debug"
4
4
 
5
5
  module IRB
6
6
  # :stopdoc:
7
7
 
8
8
  module ExtendCommand
9
- class Info < Nop
10
- def execute
11
- Class.new {
12
- def inspect
13
- str = "Ruby version: #{RUBY_VERSION}\n"
14
- str += "IRB version: #{IRB.version}\n"
15
- str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
16
- str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
17
- str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
18
- str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
19
- str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
20
- str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
21
- if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
22
- codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
23
- str += "Code page: #{codepage}\n"
24
- end
25
- str
26
- end
27
- alias_method :to_s, :inspect
28
- }.new
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(" "))
29
16
  end
30
17
  end
31
18
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: false
2
+
3
+ require_relative "nop"
4
+
5
+ module IRB
6
+ # :stopdoc:
7
+
8
+ module ExtendCommand
9
+ class IrbInfo < Nop
10
+ category "IRB"
11
+ description "Show information about IRB."
12
+
13
+ def execute
14
+ Class.new {
15
+ def inspect
16
+ str = "Ruby version: #{RUBY_VERSION}\n"
17
+ str += "IRB version: #{IRB.version}\n"
18
+ str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
19
+ str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
20
+ str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
21
+ str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
22
+ str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
23
+ str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n"
24
+ if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
25
+ codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1')
26
+ str += "Code page: #{codepage}\n"
27
+ end
28
+ str
29
+ end
30
+ alias_method :to_s, :inspect
31
+ }.new
32
+ end
33
+ end
34
+ end
35
+
36
+ # :startdoc:
37
+ end
data/lib/irb/cmd/load.rb CHANGED
@@ -17,18 +17,29 @@ module IRB
17
17
  # :stopdoc:
18
18
 
19
19
  module ExtendCommand
20
- class Load < Nop
20
+ class LoaderCommand < Nop
21
21
  include IrbLoader
22
22
 
23
- def execute(file_name, priv = nil)
24
- return irb_load(file_name, priv)
23
+ def raise_cmd_argument_error
24
+ raise CommandArgumentError.new("Please specify the file name.")
25
25
  end
26
26
  end
27
27
 
28
- class Require < Nop
29
- include IrbLoader
28
+ class Load < LoaderCommand
29
+ category "IRB"
30
+ description "Load a Ruby file."
31
+
32
+ def execute(file_name = nil, priv = nil)
33
+ raise_cmd_argument_error unless file_name
34
+ irb_load(file_name, priv)
35
+ end
36
+ end
30
37
 
31
- def execute(file_name)
38
+ class Require < LoaderCommand
39
+ category "IRB"
40
+ description "Require a Ruby file."
41
+ def execute(file_name = nil)
42
+ raise_cmd_argument_error unless file_name
32
43
 
33
44
  rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
34
45
  return false if $".find{|f| f =~ rex}
@@ -56,13 +67,16 @@ module IRB
56
67
  end
57
68
  end
58
69
 
59
- class Source < Nop
60
- include IrbLoader
61
- def execute(file_name)
70
+ class Source < LoaderCommand
71
+ category "IRB"
72
+ description "Loads a given file in the current session."
73
+
74
+ def execute(file_name = nil)
75
+ raise_cmd_argument_error unless file_name
76
+
62
77
  source_file(file_name)
63
78
  end
64
79
  end
65
80
  end
66
-
67
81
  # :startdoc:
68
82
  end
data/lib/irb/cmd/ls.rb CHANGED
@@ -9,6 +9,18 @@ module IRB
9
9
 
10
10
  module ExtendCommand
11
11
  class Ls < Nop
12
+ category "Context"
13
+ description "Show methods, constants, and variables. `-g [query]` or `-G [query]` allows you to filter out the output."
14
+
15
+ def self.transform_args(args)
16
+ if match = args&.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\n\z/)
17
+ args = match[:args]
18
+ "#{args}#{',' unless args.chomp.empty?} grep: /#{match[:grep]}/"
19
+ else
20
+ args
21
+ end
22
+ end
23
+
12
24
  def execute(*arg, grep: nil)
13
25
  o = Output.new(grep: grep)
14
26
 
@@ -21,6 +33,7 @@ module IRB
21
33
  o.dump("instance variables", obj.instance_variables)
22
34
  o.dump("class variables", klass.class_variables)
23
35
  o.dump("locals", locals)
36
+ nil
24
37
  end
25
38
 
26
39
  def dump_methods(o, klass, obj)
@@ -5,6 +5,9 @@ module IRB
5
5
 
6
6
  module ExtendCommand
7
7
  class Measure < Nop
8
+ category "Misc"
9
+ description "`measure` enables the mode to measure processing time. `measure :off` disables it."
10
+
8
11
  def initialize(*args)
9
12
  super(*args)
10
13
  end