irb 1.8.3 → 1.13.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +9 -1
  4. data/README.md +149 -25
  5. data/Rakefile +13 -3
  6. data/irb.gemspec +2 -2
  7. data/lib/irb/cmd/nop.rb +3 -52
  8. data/lib/irb/color.rb +2 -2
  9. data/lib/irb/command/backtrace.rb +17 -0
  10. data/lib/irb/command/base.rb +62 -0
  11. data/lib/irb/command/break.rb +17 -0
  12. data/lib/irb/command/catch.rb +17 -0
  13. data/lib/irb/command/chws.rb +40 -0
  14. data/lib/irb/command/context.rb +16 -0
  15. data/lib/irb/{cmd → command}/continue.rb +3 -3
  16. data/lib/irb/{cmd → command}/debug.rb +11 -20
  17. data/lib/irb/{cmd → command}/delete.rb +3 -3
  18. data/lib/irb/command/disable_irb.rb +19 -0
  19. data/lib/irb/command/edit.rb +63 -0
  20. data/lib/irb/command/exit.rb +18 -0
  21. data/lib/irb/{cmd → command}/finish.rb +3 -3
  22. data/lib/irb/command/force_exit.rb +18 -0
  23. data/lib/irb/command/help.rb +83 -0
  24. data/lib/irb/command/history.rb +45 -0
  25. data/lib/irb/command/info.rb +17 -0
  26. data/lib/irb/command/internal_helpers.rb +27 -0
  27. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  28. data/lib/irb/{cmd → command}/load.rb +23 -8
  29. data/lib/irb/{cmd → command}/ls.rb +30 -14
  30. data/lib/irb/{cmd → command}/measure.rb +18 -17
  31. data/lib/irb/{cmd → command}/next.rb +3 -3
  32. data/lib/irb/command/pushws.rb +65 -0
  33. data/lib/irb/command/show_doc.rb +51 -0
  34. data/lib/irb/command/show_source.rb +74 -0
  35. data/lib/irb/{cmd → command}/step.rb +3 -3
  36. data/lib/irb/{cmd → command}/subirb.rb +31 -17
  37. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  38. data/lib/irb/command.rb +23 -0
  39. data/lib/irb/completion.rb +74 -31
  40. data/lib/irb/context.rb +144 -57
  41. data/lib/irb/debug.rb +18 -0
  42. data/lib/irb/default_commands.rb +260 -0
  43. data/lib/irb/easter-egg.rb +16 -6
  44. data/lib/irb/ext/change-ws.rb +6 -8
  45. data/lib/irb/ext/eval_history.rb +3 -3
  46. data/lib/irb/ext/loader.rb +4 -4
  47. data/lib/irb/ext/multi-irb.rb +5 -5
  48. data/lib/irb/ext/tracer.rb +12 -51
  49. data/lib/irb/ext/use-loader.rb +6 -8
  50. data/lib/irb/ext/workspaces.rb +10 -34
  51. data/lib/irb/frame.rb +1 -1
  52. data/lib/irb/help.rb +3 -3
  53. data/lib/irb/helper_method/base.rb +16 -0
  54. data/lib/irb/helper_method/conf.rb +11 -0
  55. data/lib/irb/helper_method.rb +29 -0
  56. data/lib/irb/history.rb +15 -4
  57. data/lib/irb/init.rb +119 -52
  58. data/lib/irb/input-method.rb +77 -27
  59. data/lib/irb/inspector.rb +3 -3
  60. data/lib/irb/lc/error.rb +1 -11
  61. data/lib/irb/lc/help-message +4 -0
  62. data/lib/irb/lc/ja/error.rb +1 -11
  63. data/lib/irb/lc/ja/help-message +13 -0
  64. data/lib/irb/locale.rb +2 -2
  65. data/lib/irb/nesting_parser.rb +13 -3
  66. data/lib/irb/notifier.rb +1 -1
  67. data/lib/irb/output-method.rb +2 -8
  68. data/lib/irb/pager.rb +16 -11
  69. data/lib/irb/ruby-lex.rb +2 -2
  70. data/lib/irb/ruby_logo.aa +43 -0
  71. data/lib/irb/source_finder.rb +112 -37
  72. data/lib/irb/statement.rb +24 -24
  73. data/lib/irb/version.rb +3 -3
  74. data/lib/irb/workspace.rb +22 -6
  75. data/lib/irb/ws-for-case-2.rb +1 -1
  76. data/lib/irb/xmp.rb +3 -3
  77. data/lib/irb.rb +1071 -556
  78. data/man/irb.1 +7 -0
  79. metadata +41 -31
  80. data/lib/irb/cmd/backtrace.rb +0 -21
  81. data/lib/irb/cmd/break.rb +0 -21
  82. data/lib/irb/cmd/catch.rb +0 -21
  83. data/lib/irb/cmd/chws.rb +0 -36
  84. data/lib/irb/cmd/edit.rb +0 -60
  85. data/lib/irb/cmd/help.rb +0 -23
  86. data/lib/irb/cmd/info.rb +0 -21
  87. data/lib/irb/cmd/pushws.rb +0 -45
  88. data/lib/irb/cmd/show_cmds.rb +0 -53
  89. data/lib/irb/cmd/show_doc.rb +0 -48
  90. data/lib/irb/cmd/show_source.rb +0 -61
  91. data/lib/irb/extend-command.rb +0 -354
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # output-method.rb - output methods used by irb
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -9,16 +9,10 @@ module IRB
9
9
  # IRB::Notifier. You can define your own output method to use with Irb.new,
10
10
  # or Context.new
11
11
  class OutputMethod
12
- class NotImplementedError < StandardError
13
- def initialize(val)
14
- super("Need to define `#{val}'")
15
- end
16
- end
17
-
18
12
  # Open this method to implement your own output method, raises a
19
13
  # NotImplementedError if you don't define #print in your own class.
20
14
  def print(*opts)
21
- raise NotImplementedError, "print"
15
+ raise NotImplementedError
22
16
  end
23
17
 
24
18
  # Prints the given +opts+, with a newline delimiter.
data/lib/irb/pager.rb CHANGED
@@ -7,9 +7,9 @@ module IRB
7
7
  PAGE_COMMANDS = [ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq
8
8
 
9
9
  class << self
10
- def page_content(content)
10
+ def page_content(content, **options)
11
11
  if content_exceeds_screen_height?(content)
12
- page do |io|
12
+ page(**options) do |io|
13
13
  io.puts content
14
14
  end
15
15
  else
@@ -17,8 +17,8 @@ module IRB
17
17
  end
18
18
  end
19
19
 
20
- def page
21
- if STDIN.tty? && pager = setup_pager
20
+ def page(retain_content: false)
21
+ if should_page? && pager = setup_pager(retain_content: retain_content)
22
22
  begin
23
23
  pid = pager.pid
24
24
  yield pager
@@ -40,6 +40,10 @@ module IRB
40
40
 
41
41
  private
42
42
 
43
+ def should_page?
44
+ IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb")
45
+ end
46
+
43
47
  def content_exceeds_screen_height?(content)
44
48
  screen_height, screen_width = begin
45
49
  Reline.get_screen_size
@@ -55,19 +59,20 @@ module IRB
55
59
  pageable_height * screen_width < Reline::Unicode.calculate_width(content, true)
56
60
  end
57
61
 
58
- def setup_pager
62
+ def setup_pager(retain_content:)
59
63
  require 'shellwords'
60
64
 
61
- PAGE_COMMANDS.each do |pager|
62
- pager = Shellwords.split(pager)
63
- next if pager.empty?
65
+ PAGE_COMMANDS.each do |pager_cmd|
66
+ cmd = Shellwords.split(pager_cmd)
67
+ next if cmd.empty?
64
68
 
65
- if pager.first == 'less' || pager.first == 'more'
66
- pager << '-R' unless pager.include?('-R')
69
+ if cmd.first == 'less'
70
+ cmd << '-R' unless cmd.include?('-R')
71
+ cmd << '-X' if retain_content && !cmd.include?('-X')
67
72
  end
68
73
 
69
74
  begin
70
- io = IO.popen(pager, 'w')
75
+ io = IO.popen(cmd, 'w')
71
76
  rescue
72
77
  next
73
78
  end
data/lib/irb/ruby-lex.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/ruby-lex.rb - ruby lexcal analyzer
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -290,7 +290,7 @@ module IRB
290
290
  when :on_embdoc_beg
291
291
  indent_level = 0
292
292
  else
293
- indent_level += 1
293
+ indent_level += 1 unless t.tok == 'alias' || t.tok == 'undef'
294
294
  end
295
295
  end
296
296
  indent_level
data/lib/irb/ruby_logo.aa CHANGED
@@ -1,3 +1,4 @@
1
+ TYPE: LARGE
1
2
 
2
3
  -+smJYYN?mm-
3
4
  HB"BBYT TQg NggT
@@ -35,3 +36,45 @@
35
36
  m7 NW H N HSVO1z=?11-
36
37
  NgTH bB kH WBHWWHBHWmQgg&gggggNNN
37
38
  NNggggggNN
39
+ TYPE: ASCII
40
+ ,,,;;;;''''';;;'';,
41
+ ,,;'' ';;,;;; ',
42
+ ,,'' ;;'';'''';;;;;;
43
+ ,;' ;; ',, ;
44
+ ,;' ,;' ';, ;
45
+ ;' ,;; ',,,;
46
+ ,' ,;;,,,,,,,,,,,;;;;
47
+ ;' ;;';;;; ,;;
48
+ ;' ,;' ;; '',, ,;;;
49
+ ;; ,;' ; '';, ,; ;'
50
+ ;; ,;;' ;; ;; ;;
51
+ ;;, ,,;;' ; ;'; ;;
52
+ ;';;,,,,;;;;;;;,,, ;; ,' ; ;;
53
+ ; ;;''' ,;'; ''';,,, ; ,;' ;;;;
54
+ ;;;;, ; '; ''';;;' ';;;
55
+ ;'; ;, ;' '; ,;' ', ;;;
56
+ ;;; ; ,; '; ,,' ',, ;;
57
+ ;;; '; ;' ';,,'' ';,;;
58
+ '; ';,; ,,;''''''''';;;;;;,,;;;
59
+ ';,,;;,,;;;;;;;;;;''''''''''''''
60
+ TYPE: UNICODE
61
+ ⣀⣤⣴⣾⣿⣿⣿⡛⠛⠛⠛⠛⣻⣿⠿⠛⠛⠶⣤⡀
62
+ ⣀⣴⠾⠛⠉⠁ ⠙⣿⣶⣤⣶⣟⣉ ⠈⠻⣦
63
+ ⣀⣴⠟⠋ ⢸⣿⠟⠻⣯⡙⠛⠛⠛⠶⠶⠶⢶⣽⣇
64
+ ⣠⡾⠋⠁ ⣾⡿ ⠈⠛⢦⣄ ⣿
65
+ ⣠⡾⠋ ⣰⣿⠃ ⠙⠷⣤⡀ ⣿
66
+ ⢀⡾⠋ ⣰⣿⡏ ⠈⠻⣦⣄⢠⣿
67
+ ⣰⠟⠁ ⣴⣿⣿⣁⣀⣠⣤⣤⣤⣤⣤⣤⣤⣴⠶⠿⣿⡏
68
+ ⣼⠏ ⢀⣾⣿⠟⣿⠿⣯⣍⠁ ⣰⣿⡇
69
+ ⢀⣼⠋ ⢀⣴⣿⠟⠁ ⢸⡇ ⠙⠻⢦⣄⡀ ⢠⡿⣿⡇
70
+ ⢀⣾⡏ ⢀⣴⣿⠟⠁ ⣿ ⠉⠻⢶⣄⡀⣰⡟ ⣿⠃
71
+ ⣾⣿⠁ ⣠⣶⡿⠋⠁ ⢹⡇ ⠈⣿⡏ ⢸⣿
72
+ ⣿⣿⡆ ⢀⣠⣴⣿⡿⠋ ⠈⣿ ⢀⡾⠋⣿ ⢸⣿
73
+ ⣿⠸⣿⣶⣤⣤⣤⣤⣶⣾⠿⠿⣿⣿⠶⣤⣤⣀⡀ ⢹⡇ ⣴⠟⠁ ⣿⡀⢸⣿
74
+ ⣿⢀⣿⣟⠛⠋⠉⠁ ⢰⡟⠹⣧ ⠈⠉⠛⠻⠶⢦⣤⣀⡀ ⠈⣿ ⣠⡾⠃ ⢸⡇⢸⡇
75
+ ⣿⣾⣿⢿⡄ ⣿⠁ ⠘⣧ ⠉⠙⠛⠷⣿⣿⡋ ⠸⣇⣸⡇
76
+ ⣿⠃⣿⠈⢿⡄ ⣸⠇ ⠘⣧ ⢀⣤⠾⠋⠈⠻⣦⡀ ⣿⣿⡇
77
+ ⣿⢸⡏ ⠈⣷⡀ ⢠⡿ ⠘⣧⡀ ⣠⡴⠟⠁ ⠈⠻⣦⣀ ⢿⣿⠁
78
+ ⢻⣾⡇ ⠘⣷ ⣼⠃ ⠘⣷⣠⣴⠟⠋ ⠙⢷⣄⢸⣿
79
+ ⠻⣧⡀ ⠘⣧⣰⡏ ⢀⣠⣤⠶⠛⠉⠛⠛⠛⠛⠛⠛⠻⢶⣶⣶⣶⣶⣶⣤⣤⣽⣿⣿
80
+ ⠈⠛⠷⢦⣤⣽⣿⣥⣤⣶⣶⡿⠿⠿⠶⠶⠶⠶⠾⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠁
@@ -4,61 +4,136 @@ require_relative "ruby-lex"
4
4
 
5
5
  module IRB
6
6
  class SourceFinder
7
- Source = Struct.new(
8
- :file, # @param [String] - file name
9
- :first_line, # @param [String] - first line
10
- :last_line, # @param [String] - last line
11
- keyword_init: true,
12
- )
7
+ class EvaluationError < StandardError; end
8
+
9
+ class Source
10
+ attr_reader :file, :line
11
+ def initialize(file, line, ast_source = nil)
12
+ @file = file
13
+ @line = line
14
+ @ast_source = ast_source
15
+ end
16
+
17
+ def file_exist?
18
+ File.exist?(@file)
19
+ end
20
+
21
+ def binary_file?
22
+ # If the line is zero, it means that the target's source is probably in a binary file.
23
+ @line.zero?
24
+ end
25
+
26
+ def file_content
27
+ @file_content ||= File.read(@file)
28
+ end
29
+
30
+ def colorized_content
31
+ if !binary_file? && file_exist?
32
+ end_line = find_end
33
+ # To correctly colorize, we need to colorize full content and extract the relevant lines.
34
+ colored = IRB::Color.colorize_code(file_content)
35
+ colored.lines[@line - 1...end_line].join
36
+ elsif @ast_source
37
+ IRB::Color.colorize_code(@ast_source)
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def find_end
44
+ lex = RubyLex.new
45
+ code = file_content
46
+ lines = code.lines[(@line - 1)..-1]
47
+ tokens = RubyLex.ripper_lex_without_warning(lines.join)
48
+ prev_tokens = []
49
+
50
+ # chunk with line number
51
+ tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
52
+ code = lines[0..lnum].join
53
+ prev_tokens.concat chunk
54
+ continue = lex.should_continue?(prev_tokens)
55
+ syntax = lex.check_code_syntax(code, local_variables: [])
56
+ if !continue && syntax == :valid
57
+ return @line + lnum
58
+ end
59
+ end
60
+ @line
61
+ end
62
+ end
63
+
13
64
  private_constant :Source
14
65
 
15
66
  def initialize(irb_context)
16
67
  @irb_context = irb_context
17
68
  end
18
69
 
19
- def find_source(signature)
20
- context_binding = @irb_context.workspace.binding
70
+ def find_source(signature, super_level = 0)
21
71
  case signature
22
- when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
23
- eval(signature, context_binding) # trigger autoload
24
- base = context_binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
25
- file, line = base.const_source_location(signature)
72
+ when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName
73
+ eval_receiver_or_owner(signature) # trigger autoload
74
+ *parts, name = signature.split('::', -1)
75
+ base =
76
+ if parts.empty? # ConstName
77
+ find_const_owner(name)
78
+ elsif parts == [''] # ::ConstName
79
+ Object
80
+ else # ConstPath::ConstName
81
+ eval_receiver_or_owner(parts.join('::'))
82
+ end
83
+ file, line = base.const_source_location(name)
26
84
  when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
27
- owner = eval(Regexp.last_match[:owner], context_binding)
85
+ owner = eval_receiver_or_owner(Regexp.last_match[:owner])
28
86
  method = Regexp.last_match[:method]
29
- if owner.respond_to?(:instance_method)
30
- methods = owner.instance_methods + owner.private_instance_methods
31
- file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
32
- end
87
+ return unless owner.respond_to?(:instance_method)
88
+ method = method_target(owner, super_level, method, "owner")
89
+ file, line = method&.source_location
33
90
  when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
34
- receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding)
91
+ receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self')
35
92
  method = Regexp.last_match[:method]
36
- file, line = receiver.method(method).source_location if receiver.respond_to?(method, true)
93
+ return unless receiver.respond_to?(method, true)
94
+ method = method_target(receiver, super_level, method, "receiver")
95
+ file, line = method&.source_location
37
96
  end
38
- if file && line && File.exist?(file)
39
- Source.new(file: file, first_line: line, last_line: find_end(file, line))
97
+ return unless file && line
98
+
99
+ if File.exist?(file)
100
+ Source.new(file, line)
101
+ elsif method
102
+ # Method defined with eval, probably in IRB session
103
+ source = RubyVM::AbstractSyntaxTree.of(method)&.source rescue nil
104
+ Source.new(file, line, source)
40
105
  end
106
+ rescue EvaluationError
107
+ nil
41
108
  end
42
109
 
43
110
  private
44
111
 
45
- def find_end(file, first_line)
46
- lex = RubyLex.new
47
- lines = File.read(file).lines[(first_line - 1)..-1]
48
- tokens = RubyLex.ripper_lex_without_warning(lines.join)
49
- prev_tokens = []
50
-
51
- # chunk with line number
52
- tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
53
- code = lines[0..lnum].join
54
- prev_tokens.concat chunk
55
- continue = lex.should_continue?(prev_tokens)
56
- syntax = lex.check_code_syntax(code, local_variables: [])
57
- if !continue && syntax == :valid
58
- return first_line + lnum
59
- end
112
+ def method_target(owner_receiver, super_level, method, type)
113
+ case type
114
+ when "owner"
115
+ target_method = owner_receiver.instance_method(method)
116
+ when "receiver"
117
+ target_method = owner_receiver.method(method)
118
+ end
119
+ super_level.times do |s|
120
+ target_method = target_method.super_method if target_method
60
121
  end
61
- first_line
122
+ target_method
123
+ rescue NameError
124
+ nil
125
+ end
126
+
127
+ def eval_receiver_or_owner(code)
128
+ context_binding = @irb_context.workspace.binding
129
+ eval(code, context_binding)
130
+ rescue NameError
131
+ raise EvaluationError
132
+ end
133
+
134
+ def find_const_owner(name)
135
+ module_nesting = @irb_context.workspace.binding.eval('::Module.nesting')
136
+ module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object
62
137
  end
63
138
  end
64
139
  end
data/lib/irb/statement.rb CHANGED
@@ -16,8 +16,23 @@ module IRB
16
16
  raise NotImplementedError
17
17
  end
18
18
 
19
- def evaluable_code
20
- raise NotImplementedError
19
+ class EmptyInput < Statement
20
+ def is_assignment?
21
+ false
22
+ end
23
+
24
+ def suppresses_echo?
25
+ true
26
+ end
27
+
28
+ # Debugger takes empty input to repeat the last command
29
+ def should_be_handled_by_debugger?
30
+ true
31
+ end
32
+
33
+ def code
34
+ ""
35
+ end
21
36
  end
22
37
 
23
38
  class Expression < Statement
@@ -37,18 +52,15 @@ module IRB
37
52
  def is_assignment?
38
53
  @is_assignment
39
54
  end
40
-
41
- def evaluable_code
42
- @code
43
- end
44
55
  end
45
56
 
46
57
  class Command < Statement
47
- def initialize(code, command, arg, command_class)
48
- @code = code
49
- @command = command
50
- @arg = arg
58
+ attr_reader :command_class, :arg
59
+
60
+ def initialize(original_code, command_class, arg)
61
+ @code = original_code
51
62
  @command_class = command_class
63
+ @arg = arg
52
64
  end
53
65
 
54
66
  def is_assignment?
@@ -60,20 +72,8 @@ module IRB
60
72
  end
61
73
 
62
74
  def should_be_handled_by_debugger?
63
- require_relative 'cmd/help'
64
- require_relative 'cmd/debug'
65
- IRB::ExtendCommand::DebugCommand > @command_class || IRB::ExtendCommand::Help == @command_class
66
- end
67
-
68
- def evaluable_code
69
- # Hook command-specific transformation to return valid Ruby code
70
- if @command_class.respond_to?(:transform_args)
71
- arg = @command_class.transform_args(@arg)
72
- else
73
- arg = @arg
74
- end
75
-
76
- [@command, arg].compact.join(' ')
75
+ require_relative 'command/debug'
76
+ IRB::Command::DebugCommand > @command_class
77
77
  end
78
78
  end
79
79
  end
data/lib/irb/version.rb CHANGED
@@ -1,11 +1,11 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/version.rb - irb version definition file
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.8.3"
8
+ VERSION = "1.13.1"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2023-10-14"
10
+ @LAST_UPDATE_DATE = "2024-05-05"
11
11
  end
data/lib/irb/workspace.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/workspace-binding.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -6,6 +6,8 @@
6
6
 
7
7
  require "delegate"
8
8
 
9
+ require_relative "helper_method"
10
+
9
11
  IRB::TOPLEVEL_BINDING = binding
10
12
  module IRB # :nodoc:
11
13
  class WorkSpace
@@ -90,11 +92,11 @@ EOF
90
92
  IRB.conf[:__MAIN__] = @main
91
93
  @main.singleton_class.class_eval do
92
94
  private
93
- define_method(:exit) do |*a, &b|
94
- # Do nothing, will be overridden
95
- end
96
95
  define_method(:binding, Kernel.instance_method(:binding))
97
96
  define_method(:local_variables, Kernel.instance_method(:local_variables))
97
+ # Define empty method to avoid delegator warning, will be overridden.
98
+ define_method(:exit) {|*a, &b| }
99
+ define_method(:exit!) {|*a, &b| }
98
100
  end
99
101
  @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
100
102
  end
@@ -108,8 +110,10 @@ EOF
108
110
  # <code>IRB.conf[:__MAIN__]</code>
109
111
  attr_reader :main
110
112
 
111
- def load_commands_to_main
112
- main.extend ExtendCommandBundle
113
+ def load_helper_methods_to_main
114
+ ancestors = class<<main;ancestors;end
115
+ main.extend ExtendCommandBundle if !ancestors.include?(ExtendCommandBundle)
116
+ main.extend HelpersContainer if !ancestors.include?(HelpersContainer)
113
117
  end
114
118
 
115
119
  # Evaluate the given +statements+ within the context of this workspace.
@@ -170,4 +174,16 @@ EOF
170
174
  "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n"
171
175
  end
172
176
  end
177
+
178
+ module HelpersContainer
179
+ def self.install_helper_methods
180
+ HelperMethod.helper_methods.each do |name, helper_method_class|
181
+ define_method name do |*args, **opts, &block|
182
+ helper_method_class.instance.execute(*args, **opts, &block)
183
+ end unless method_defined?(name)
184
+ end
185
+ end
186
+
187
+ install_helper_methods
188
+ end
173
189
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/ws-for-case-2.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
data/lib/irb/xmp.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # xmp.rb - irb version of gotoken xmp
4
4
  # by Keiju ISHITSUKA(Nippon Rational Inc.)
@@ -44,8 +44,8 @@ class XMP
44
44
  # The top-level binding or, optional +bind+ parameter will be used when
45
45
  # creating the workspace. See WorkSpace.new for more information.
46
46
  #
47
- # This uses the +:XMP+ prompt mode, see IRB@Customizing+the+IRB+Prompt for
48
- # full detail.
47
+ # This uses the +:XMP+ prompt mode.
48
+ # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information.
49
49
  def initialize(bind = nil)
50
50
  IRB.init_config(nil)
51
51