irb 1.14.1 → 1.14.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b71e88a4dbaabac4d4a40667f3bd763bd05dfda12832919e44072f04f85ceb4
4
- data.tar.gz: 213f59cc1bc59c61ea2013e81a098d0cb1c95f9972233cb8886bb7b353884fe8
3
+ metadata.gz: 606da5c01c0630f572812c844da8f331fd487fa50060db8c95a61aef14660d68
4
+ data.tar.gz: 5d1749fea9672c734b9bdce740f6f43d90b2479e2a06de09d9604265317fab1e
5
5
  SHA512:
6
- metadata.gz: 2ed2dd4b075b7e54ca58bf206c9dca68163564f5bbdbd8bacb24479af62a2b0bbef9d612ae0af0075bda787e189c6020b953c1858e5faecfbab7e9e441d83952
7
- data.tar.gz: 6a81b55c3f04253913c0c1adcc118d61c03cb0b7a5a64410bbfe5495b2fc6d08e0a451eb21302327454f73ef83ed54d74c23ef065139fedbd3a685b1c5562c63
6
+ metadata.gz: 478ceef6ddf60e4bf8ddf2f1586129eab9bcff9e40bb9af8662a1c7f46d7c406f7d896395d3459cbde5ac2a427b73e474327033647e6c742691c185a553a1d71
7
+ data.tar.gz: da1f92f1403c9fee631f7fc85f1bf60120db710bd171a98be1b428a22c4545fed4d4e4dd7692d90220520609047bd4fc6d00882da0bce7bf1a67e05dc41dd8e1
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/
7
7
 
8
8
  if is_unix && ENV['WITH_VTERM']
9
9
  gem "vterm", github: "ruby/vterm-gem"
10
- gem "yamatanooroti", github: "ruby/yamatanooroti", ref: "f6e47192100d6089f70cf64c1de540dcaadf005a"
10
+ gem "yamatanooroti", github: "ruby/yamatanooroti"
11
11
  end
12
12
 
13
13
  gem "stackprof" if is_unix && !is_truffleruby
data/README.md CHANGED
@@ -170,6 +170,13 @@ Aliases
170
170
 
171
171
  ## Debugging with IRB
172
172
 
173
+ ### Getting Started
174
+
175
+ - In `binding.irb`, use the `debug` command to start a `irb:rdbg` session with access to all `debug.gem` commands.
176
+ - Use `RUBY_DEBUG_IRB_CONSOLE=1` environment variable to make `debug.gem` use IRB as the debugging console.
177
+
178
+ ### Details
179
+
173
180
  Starting from version 1.8.0, IRB boasts a powerful integration with `debug.gem`, providing a debugging experience akin to `pry-byebug`.
174
181
 
175
182
  After hitting a `binding.irb` breakpoint, you can activate the debugger with the `debug` command. Alternatively, if the `debug` method happens to already be defined in the current scope, you can call `irb_debug`.
@@ -354,6 +361,10 @@ irb(main):002> a.first. # Completes Integer methods
354
361
  - `VISUAL`: Its value would be used to open files by the `edit` command.
355
362
  - `EDITOR`: Its value would be used to open files by the `edit` command if `VISUAL` is unset.
356
363
  - `IRBRC`: The file specified would be evaluated as IRB's rc-file.
364
+ - `XDG_CONFIG_HOME`: If it is set and `IRBRC` is unset, the file `$XDG_CONFIG_HOME/irb/irbrc` would be evaluated as IRB's rc-file.
365
+ - `RI_PAGER`: The command specified would be used as a pager.
366
+ - `PAGER`: The command specified would be used as a pager if `RI_PAGER` is unset.
367
+ - `IRB_LANG`, `LC_MESSAGES`, `LC_ALL`, `LANG`: The first of these that is set would be used as the locale value.
357
368
 
358
369
  ## Documentation
359
370
 
@@ -19,7 +19,7 @@ module IRB
19
19
  # Use throw and catch to handle arg that includes `;`
20
20
  # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }]
21
21
  catch(:EXTRACT_RUBY_ARGS) do
22
- @irb_context.workspace.binding.eval "IRB::Command.extract_ruby_args #{arg}"
22
+ @irb_context.workspace.binding.eval "::IRB::Command.extract_ruby_args #{arg}"
23
23
  end || [[], {}]
24
24
  end
25
25
  end
@@ -11,7 +11,7 @@ module IRB
11
11
 
12
12
  module Command
13
13
  class Ls < Base
14
- include RubyArgsExtractor
14
+ class EvaluationError < StandardError; end
15
15
 
16
16
  category "Context"
17
17
  description "Show methods, constants, and variables."
@@ -22,24 +22,35 @@ module IRB
22
22
  -g [query] Filter the output with a query.
23
23
  HELP_MESSAGE
24
24
 
25
+ def evaluate(code)
26
+ @irb_context.workspace.binding.eval(code)
27
+ rescue Exception => e
28
+ puts "#{e.class}: #{e.message}"
29
+ raise EvaluationError
30
+ end
31
+
25
32
  def execute(arg)
26
33
  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
34
+ target = match[:target]
32
35
  grep = Regexp.new(match[:grep])
36
+ elsif match = arg.match(/\A((?<target>.+),|)\s*grep:(?<grep>.+)/)
37
+ # Legacy style `ls obj, grep: /regexp/`
38
+ # Evaluation order should be eval(target) then eval(grep)
39
+ target = match[:target] || ''
40
+ grep_regexp_code = match[:grep]
33
41
  else
34
- args, kwargs = ruby_args(arg)
35
- use_main = args.empty?
36
- obj = args.first
37
- grep = kwargs[:grep]
42
+ target = arg.strip
38
43
  end
39
44
 
40
- if use_main
45
+ if target.empty?
41
46
  obj = irb_context.workspace.main
42
47
  locals = irb_context.workspace.binding.local_variables
48
+ else
49
+ obj = evaluate(target)
50
+ end
51
+
52
+ if grep_regexp_code
53
+ grep = evaluate(grep_regexp_code)
43
54
  end
44
55
 
45
56
  o = Output.new(grep: grep)
@@ -52,6 +63,7 @@ module IRB
52
63
  o.dump("class variables", klass.class_variables)
53
64
  o.dump("locals", locals) if locals
54
65
  o.print_result
66
+ rescue EvaluationError
55
67
  end
56
68
 
57
69
  def dump_methods(o, klass, obj)
@@ -137,26 +137,33 @@ module IRB
137
137
  end
138
138
 
139
139
  class RegexpCompletor < BaseCompletor # :nodoc:
140
+ KERNEL_METHODS = ::Kernel.instance_method(:methods)
141
+ KERNEL_PRIVATE_METHODS = ::Kernel.instance_method(:private_methods)
142
+ KERNEL_INSTANCE_VARIABLES = ::Kernel.instance_method(:instance_variables)
143
+ OBJECT_CLASS_INSTANCE_METHOD = ::Object.instance_method(:class)
144
+ MODULE_CONSTANTS_INSTANCE_METHOD = ::Module.instance_method(:constants)
145
+
140
146
  using Module.new {
141
147
  refine ::Binding do
142
148
  def eval_methods
143
- ::Kernel.instance_method(:methods).bind(eval("self")).call
149
+ KERNEL_METHODS.bind_call(receiver)
144
150
  end
145
151
 
146
152
  def eval_private_methods
147
- ::Kernel.instance_method(:private_methods).bind(eval("self")).call
153
+ KERNEL_PRIVATE_METHODS.bind_call(receiver)
148
154
  end
149
155
 
150
156
  def eval_instance_variables
151
- ::Kernel.instance_method(:instance_variables).bind(eval("self")).call
157
+ KERNEL_INSTANCE_VARIABLES.bind_call(receiver)
152
158
  end
153
159
 
154
160
  def eval_global_variables
155
- ::Kernel.instance_method(:global_variables).bind(eval("self")).call
161
+ ::Kernel.global_variables
156
162
  end
157
163
 
158
164
  def eval_class_constants
159
- ::Module.instance_method(:constants).bind(eval("self.class")).call
165
+ klass = OBJECT_CLASS_INSTANCE_METHOD.bind_call(receiver)
166
+ MODULE_CONSTANTS_INSTANCE_METHOD.bind_call(klass)
160
167
  end
161
168
  end
162
169
  }
data/lib/irb/context.rb CHANGED
@@ -13,6 +13,9 @@ module IRB
13
13
  # A class that wraps the current state of the irb session, including the
14
14
  # configuration of IRB.conf.
15
15
  class Context
16
+ KERNEL_PUBLIC_METHOD = ::Kernel.instance_method(:public_method)
17
+ KERNEL_METHOD = ::Kernel.instance_method(:method)
18
+
16
19
  ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
17
20
  # Creates a new IRB context.
18
21
  #
@@ -176,11 +179,17 @@ module IRB
176
179
 
177
180
  private def build_completor
178
181
  completor_type = IRB.conf[:COMPLETOR]
182
+
183
+ # Gem repl_type_completor is added to bundled gems in Ruby 3.4.
184
+ # Use :type as default completor only in Ruby 3.4 or later.
185
+ verbose = !!completor_type
186
+ completor_type ||= RUBY_VERSION >= '3.4' ? :type : :regexp
187
+
179
188
  case completor_type
180
189
  when :regexp
181
190
  return RegexpCompletor.new
182
191
  when :type
183
- completor = build_type_completor
192
+ completor = build_type_completor(verbose: verbose)
184
193
  return completor if completor
185
194
  else
186
195
  warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}"
@@ -189,17 +198,17 @@ module IRB
189
198
  RegexpCompletor.new
190
199
  end
191
200
 
192
- private def build_type_completor
201
+ private def build_type_completor(verbose:)
193
202
  if RUBY_ENGINE == 'truffleruby'
194
203
  # Avoid SyntaxError. truffleruby does not support endless method definition yet.
195
- warn 'TypeCompletor is not supported on TruffleRuby yet'
204
+ warn 'TypeCompletor is not supported on TruffleRuby yet' if verbose
196
205
  return
197
206
  end
198
207
 
199
208
  begin
200
209
  require 'repl_type_completor'
201
210
  rescue LoadError => e
202
- warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
211
+ warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}" if verbose
203
212
  return
204
213
  end
205
214
 
@@ -642,8 +651,8 @@ module IRB
642
651
  return if local_variables.include?(command)
643
652
 
644
653
  # Check visibility
645
- public_method = !!Kernel.instance_method(:public_method).bind_call(main, command) rescue false
646
- private_method = !public_method && !!Kernel.instance_method(:method).bind_call(main, command) rescue false
654
+ public_method = !!KERNEL_PUBLIC_METHOD.bind_call(main, command) rescue false
655
+ private_method = !public_method && !!KERNEL_METHOD.bind_call(main, command) rescue false
647
656
  if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
648
657
  [command, arg]
649
658
  end
@@ -698,5 +707,10 @@ module IRB
698
707
  def local_variables # :nodoc:
699
708
  workspace.binding.local_variables
700
709
  end
710
+
711
+ def safe_method_call_on_main(method_name)
712
+ main_object = main
713
+ Object === main_object ? main_object.__send__(method_name) : Object.instance_method(method_name).bind_call(main_object)
714
+ end
701
715
  end
702
716
  end
data/lib/irb/debug/ui.rb CHANGED
@@ -45,9 +45,7 @@ module IRB
45
45
  $stdout.puts line.chomp
46
46
  }
47
47
  when String
48
- str.each_line{|line|
49
- $stdout.puts line.chomp
50
- }
48
+ Pager.page_content(str, retain_content: true)
51
49
  when nil
52
50
  $stdout.puts
53
51
  end
@@ -56,7 +54,7 @@ module IRB
56
54
  def readline _
57
55
  setup_interrupt do
58
56
  tc = DEBUGGER__::SESSION.instance_variable_get(:@tc)
59
- cmd = @irb.debug_readline(tc.current_frame.binding || TOPLEVEL_BINDING)
57
+ cmd = @irb.debug_readline(tc.current_frame.eval_binding || TOPLEVEL_BINDING)
60
58
 
61
59
  case cmd
62
60
  when nil # when user types C-d
@@ -125,7 +125,7 @@ module IRB
125
125
  canvas = Canvas.new(Reline.get_screen_size)
126
126
  end
127
127
  ruby_model = RubyModel.new
128
- print "\e[?1049h"
128
+ print "\e[?25l" # hide cursor
129
129
  0.step do |i| # TODO (0..).each needs Ruby 2.6 or later
130
130
  buff = canvas.draw do
131
131
  ruby_model.render_frame(i) do |p1, p2|
@@ -139,6 +139,7 @@ module IRB
139
139
  end
140
140
  rescue Interrupt
141
141
  ensure
142
+ print "\e[?25h" # show cursor
142
143
  trap("SIGINT", prev_trap)
143
144
  end
144
145
  end
data/lib/irb/history.rb CHANGED
@@ -1,6 +1,32 @@
1
1
  require "pathname"
2
2
 
3
3
  module IRB
4
+ module History
5
+ class << self
6
+ # Integer representation of <code>IRB.conf[:HISTORY_FILE]</code>.
7
+ def save_history
8
+ IRB.conf[:SAVE_HISTORY].to_i
9
+ end
10
+
11
+ def save_history?
12
+ !save_history.zero?
13
+ end
14
+
15
+ def infinite?
16
+ save_history.negative?
17
+ end
18
+
19
+ # Might be nil when HOME and XDG_CONFIG_HOME are not available.
20
+ def history_file
21
+ if (history_file = IRB.conf[:HISTORY_FILE])
22
+ File.expand_path(history_file)
23
+ else
24
+ IRB.rc_file("_history")
25
+ end
26
+ end
27
+ end
28
+ end
29
+
4
30
  module HistorySavingAbility # :nodoc:
5
31
  def support_history_saving?
6
32
  true
@@ -11,76 +37,75 @@ module IRB
11
37
  end
12
38
 
13
39
  def load_history
40
+ history_file = History.history_file
41
+ return unless File.exist?(history_file.to_s)
42
+
14
43
  history = self.class::HISTORY
15
44
 
16
- if history_file = IRB.conf[:HISTORY_FILE]
17
- history_file = File.expand_path(history_file)
18
- end
19
- history_file = IRB.rc_file("_history") unless history_file
20
- if history_file && File.exist?(history_file)
21
- File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
22
- f.each { |l|
23
- l = l.chomp
24
- if self.class == RelineInputMethod and history.last&.end_with?("\\")
25
- history.last.delete_suffix!("\\")
26
- history.last << "\n" << l
27
- else
28
- history << l
29
- end
30
- }
31
- end
32
- @loaded_history_lines = history.size
33
- @loaded_history_mtime = File.mtime(history_file)
45
+ File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
46
+ f.each { |l|
47
+ l = l.chomp
48
+ if self.class == RelineInputMethod and history.last&.end_with?("\\")
49
+ history.last.delete_suffix!("\\")
50
+ history.last << "\n" << l
51
+ else
52
+ history << l
53
+ end
54
+ }
34
55
  end
56
+ @loaded_history_lines = history.size
57
+ @loaded_history_mtime = File.mtime(history_file)
35
58
  end
36
59
 
37
60
  def save_history
61
+ return unless History.save_history?
62
+ return unless (history_file = History.history_file)
63
+ unless ensure_history_file_writable(history_file)
64
+ warn <<~WARN
65
+ Can't write history to #{History.history_file.inspect} due to insufficient permissions.
66
+ Please verify the value of `IRB.conf[:HISTORY_FILE]`. Ensure the folder exists and that both the folder and file (if it exists) are writable.
67
+ WARN
68
+ return
69
+ end
70
+
38
71
  history = self.class::HISTORY.to_a
39
72
 
40
- if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) != 0
41
- if history_file = IRB.conf[:HISTORY_FILE]
42
- history_file = File.expand_path(history_file)
43
- end
44
- history_file = IRB.rc_file("_history") unless history_file
73
+ if File.exist?(history_file) &&
74
+ File.mtime(history_file) != @loaded_history_mtime
75
+ history = history[@loaded_history_lines..-1] if @loaded_history_lines
76
+ append_history = true
77
+ end
45
78
 
46
- # When HOME and XDG_CONFIG_HOME are not available, history_file might be nil
47
- return unless history_file
79
+ File.open(history_file, (append_history ? "a" : "w"), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
80
+ hist = history.map { |l| l.scrub.split("\n").join("\\\n") }
48
81
 
49
- # Change the permission of a file that already exists[BUG #7694]
50
- begin
51
- if File.stat(history_file).mode & 066 != 0
52
- File.chmod(0600, history_file)
53
- end
54
- rescue Errno::ENOENT
55
- rescue Errno::EPERM
56
- return
57
- rescue
58
- raise
82
+ unless append_history || History.infinite?
83
+ # Check size before slicing because array.last(huge_number) raises RangeError.
84
+ hist = hist.last(History.save_history) if hist.size > History.save_history
59
85
  end
60
86
 
61
- if File.exist?(history_file) &&
62
- File.mtime(history_file) != @loaded_history_mtime
63
- history = history[@loaded_history_lines..-1] if @loaded_history_lines
64
- append_history = true
65
- end
87
+ f.puts(hist)
88
+ end
89
+ end
66
90
 
67
- pathname = Pathname.new(history_file)
68
- unless Dir.exist?(pathname.dirname)
69
- warn "Warning: The directory to save IRB's history file does not exist. Please double check `IRB.conf[:HISTORY_FILE]`'s value."
70
- return
71
- end
91
+ private
72
92
 
73
- File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
74
- hist = history.map{ |l| l.scrub.split("\n").join("\\\n") }
75
- unless append_history
76
- begin
77
- hist = hist.last(num) if hist.size > num and num > 0
78
- rescue RangeError # bignum too big to convert into `long'
79
- # Do nothing because the bignum should be treated as infinity
80
- end
81
- end
82
- f.puts(hist)
93
+ # Returns boolean whether writing to +history_file+ will be possible.
94
+ # Permissions of already existing +history_file+ are changed to
95
+ # owner-only-readable if necessary [BUG #7694].
96
+ def ensure_history_file_writable(history_file)
97
+ history_file = Pathname.new(history_file)
98
+
99
+ return false unless history_file.dirname.writable?
100
+ return true unless history_file.exist?
101
+
102
+ begin
103
+ if history_file.stat.mode & 0o66 != 0
104
+ history_file.chmod 0o600
83
105
  end
106
+ true
107
+ rescue Errno::EPERM # no permissions
108
+ false
84
109
  end
85
110
  end
86
111
  end
data/lib/irb/init.rb CHANGED
@@ -80,7 +80,7 @@ module IRB # :nodoc:
80
80
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
81
81
  @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
82
82
  @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
83
- @CONF[:COMPLETOR] = ENV.fetch("IRB_COMPLETOR", "regexp").to_sym
83
+ @CONF[:COMPLETOR] = ENV["IRB_COMPLETOR"]&.to_sym
84
84
  @CONF[:INSPECT_MODE] = true
85
85
  @CONF[:USE_TRACER] = false
86
86
  @CONF[:USE_LOADER] = false
@@ -67,7 +67,9 @@ module IRB
67
67
  #
68
68
  # See IO#gets for more information.
69
69
  def gets
70
- puts if @stdout.tty? # workaround for debug compatibility test
70
+ # Workaround for debug compatibility test https://github.com/ruby/debug/pull/1100
71
+ puts if ENV['RUBY_DEBUG_TEST_UI']
72
+
71
73
  print @prompt
72
74
  line = @stdin.gets
73
75
  @line[@line_no += 1] = line
@@ -346,9 +348,15 @@ module IRB
346
348
  if show_easter_egg
347
349
  IRB.__send__(:easter_egg)
348
350
  else
351
+ # RDoc::RI::Driver#display_names uses pager command internally.
352
+ # Some pager command like `more` doesn't use alternate screen
353
+ # so we need to turn on and off alternate screen manually.
349
354
  begin
355
+ print "\e[?1049h"
350
356
  driver.display_names([name])
351
357
  rescue RDoc::RI::Driver::NotFoundError
358
+ ensure
359
+ print "\e[?1049l"
352
360
  end
353
361
  end
354
362
  end
@@ -8,7 +8,7 @@ Usage: irb.rb [options] [programfile] [arguments]
8
8
  -w ruby -w と同じ.
9
9
  -W[level=2] ruby -W と同じ.
10
10
  --context-mode n 新しいワークスペースを作成した時に関連する Binding
11
- オブジェクトの作成方法を 0 から 3 のいずれかに設定する.
11
+ オブジェクトの作成方法を 0 から 4 のいずれかに設定する.
12
12
  --extra-doc-dir 指定したディレクトリのドキュメントを追加で読み込む.
13
13
  --echo 実行結果を表示する(デフォルト).
14
14
  --noecho 実行結果を表示しない.
@@ -33,9 +33,9 @@ Usage: irb.rb [options] [programfile] [arguments]
33
33
  補完に正規表現を利用する.
34
34
  --type-completor 補完に型情報を利用する.
35
35
  --prompt prompt-mode/--prompt-mode prompt-mode
36
- プロンプトモードを切替えます. 現在定義されているプ
37
- ロンプトモードは, default, simple, xmp, inf-rubyが
38
- 用意されています.
36
+ プロンプトモードを切り替える.
37
+ 現在定義されているプロンプトモードは,
38
+ default, classic, simple, inf-ruby, xmp, null.
39
39
  --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特
40
40
  に指定がない限り, シングルラインエディタとマルチラ
41
41
  インエディタは使わなくなる.
@@ -159,7 +159,7 @@ module IRB
159
159
  when :on_heredoc_end
160
160
  opens.pop
161
161
  when :on_backtick
162
- opens << [t, nil] if t.state.allbits?(Ripper::EXPR_BEG)
162
+ opens << [t, nil] unless t.state == Ripper::EXPR_ARG
163
163
  when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg
164
164
  opens << [t, nil]
165
165
  when :on_tstring_end, :on_regexp_end, :on_label_end
data/lib/irb/pager.rb CHANGED
@@ -34,7 +34,12 @@ module IRB
34
34
  # So to properly terminate the pager with Ctrl-C, we need to catch `IRB::Abort` and kill the pager process
35
35
  rescue IRB::Abort
36
36
  begin
37
- Process.kill("TERM", pid) if pid
37
+ begin
38
+ Process.kill("TERM", pid) if pid
39
+ rescue Errno::EINVAL
40
+ # SIGTERM not supported (windows)
41
+ Process.kill("KILL", pid)
42
+ end
38
43
  rescue Errno::ESRCH
39
44
  # Pager process already terminated
40
45
  end
@@ -125,9 +125,8 @@ module IRB
125
125
  end
126
126
 
127
127
  def eval_receiver_or_owner(code)
128
- context_binding = @irb_context.workspace.binding
129
- eval(code, context_binding)
130
- rescue NameError
128
+ @irb_context.workspace.binding.eval(code)
129
+ rescue Exception
131
130
  raise EvaluationError
132
131
  end
133
132
 
data/lib/irb/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.14.1"
8
+ VERSION = "1.14.2"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2024-09-25"
10
+ @LAST_UPDATE_DATE = "2024-12-12"
11
11
  end
data/lib/irb/workspace.rb CHANGED
@@ -4,8 +4,6 @@
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
- require "delegate"
8
-
9
7
  require_relative "helper_method"
10
8
 
11
9
  IRB::TOPLEVEL_BINDING = binding
@@ -16,7 +14,7 @@ module IRB # :nodoc:
16
14
  # set self to main if specified, otherwise
17
15
  # inherit main from TOPLEVEL_BINDING.
18
16
  def initialize(*main)
19
- if main[0].kind_of?(Binding)
17
+ if Binding === main[0]
20
18
  @binding = main.shift
21
19
  elsif IRB.conf[:SINGLE_IRB]
22
20
  @binding = TOPLEVEL_BINDING
@@ -70,37 +68,16 @@ EOF
70
68
  unless main.empty?
71
69
  case @main
72
70
  when Module
73
- @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
71
+ @binding = eval("::IRB.conf[:__MAIN__].module_eval('::Kernel.binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
74
72
  else
75
73
  begin
76
- @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
74
+ @binding = eval("::IRB.conf[:__MAIN__].instance_eval('::Kernel.binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
77
75
  rescue TypeError
78
76
  fail CantChangeBinding, @main.inspect
79
77
  end
80
78
  end
81
79
  end
82
80
 
83
- case @main
84
- when Object
85
- use_delegator = @main.frozen?
86
- else
87
- use_delegator = true
88
- end
89
-
90
- if use_delegator
91
- @main = SimpleDelegator.new(@main)
92
- IRB.conf[:__MAIN__] = @main
93
- @main.singleton_class.class_eval do
94
- private
95
- define_method(:binding, Kernel.instance_method(:binding))
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| }
100
- end
101
- @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
102
- end
103
-
104
81
  @binding.local_variable_set(:_, nil)
105
82
  end
106
83
 
@@ -111,6 +88,9 @@ EOF
111
88
  attr_reader :main
112
89
 
113
90
  def load_helper_methods_to_main
91
+ # Do not load helper methods to frozen objects and BasicObject
92
+ return unless Object === @main && !@main.frozen?
93
+
114
94
  ancestors = class<<main;ancestors;end
115
95
  main.extend ExtendCommandBundle if !ancestors.include?(ExtendCommandBundle)
116
96
  main.extend HelpersContainer if !ancestors.include?(HelpersContainer)
data/lib/irb.rb CHANGED
@@ -14,6 +14,7 @@ require_relative "irb/default_commands"
14
14
 
15
15
  require_relative "irb/ruby-lex"
16
16
  require_relative "irb/statement"
17
+ require_relative "irb/history"
17
18
  require_relative "irb/input-method"
18
19
  require_relative "irb/locale"
19
20
  require_relative "irb/color"
@@ -220,11 +221,11 @@ require_relative "irb/pager"
220
221
  # *new_filepath*, which becomes the history file for the session.
221
222
  #
222
223
  # You can change the number of commands saved by adding to your configuration
223
- # file: `IRB.conf[:SAVE_HISTORY] = *n*`, wheHISTORY_FILEre *n* is one of:
224
+ # file: `IRB.conf[:SAVE_HISTORY] = *n*`, where *n* is one of:
224
225
  #
225
- # * Positive integer: the number of commands to be saved,
226
- # * Zero: all commands are to be saved.
227
- # * `nil`: no commands are to be saved,.
226
+ # * Positive integer: the number of commands to be saved.
227
+ # * Negative integer: all commands are to be saved.
228
+ # * Zero or `nil`: no commands are to be saved.
228
229
  #
229
230
  #
230
231
  # During the session, you can use methods `conf.save_history` or
@@ -972,7 +973,7 @@ module IRB
972
973
  # debugger.
973
974
  input = nil
974
975
  forced_exit = catch(:IRB_EXIT) do
975
- if IRB.conf[:SAVE_HISTORY] && context.io.support_history_saving?
976
+ if History.save_history? && context.io.support_history_saving?
976
977
  # Previous IRB session's history has been saved when `Irb#run` is exited We need
977
978
  # to make sure the saved history is not saved again by resetting the counter
978
979
  context.io.reset_history_counter
@@ -1003,9 +1004,10 @@ module IRB
1003
1004
  prev_context = conf[:MAIN_CONTEXT]
1004
1005
  conf[:MAIN_CONTEXT] = context
1005
1006
 
1006
- save_history = !in_nested_session && conf[:SAVE_HISTORY] && context.io.support_history_saving?
1007
+ load_history = !in_nested_session && context.io.support_history_saving?
1008
+ save_history = load_history && History.save_history?
1007
1009
 
1008
- if save_history
1010
+ if load_history
1009
1011
  context.io.load_history
1010
1012
  end
1011
1013
 
@@ -1130,7 +1132,7 @@ module IRB
1130
1132
  return Statement::EmptyInput.new
1131
1133
  end
1132
1134
 
1133
- code.force_encoding(@context.io.encoding)
1135
+ code = code.dup.force_encoding(@context.io.encoding)
1134
1136
  if (command, arg = @context.parse_command(code))
1135
1137
  command_class = Command.load_command(command)
1136
1138
  Statement::Command.new(code, command_class, arg)
@@ -1467,10 +1469,10 @@ module IRB
1467
1469
  when "N"
1468
1470
  @context.irb_name
1469
1471
  when "m"
1470
- main_str = @context.main.to_s rescue "!#{$!.class}"
1472
+ main_str = @context.safe_method_call_on_main(:to_s) rescue "!#{$!.class}"
1471
1473
  truncate_prompt_main(main_str)
1472
1474
  when "M"
1473
- main_str = @context.main.inspect rescue "!#{$!.class}"
1475
+ main_str = @context.safe_method_call_on_main(:inspect) rescue "!#{$!.class}"
1474
1476
  truncate_prompt_main(main_str)
1475
1477
  when "l"
1476
1478
  ltype
data/man/irb.1 CHANGED
@@ -180,7 +180,7 @@ The default value is 16.
180
180
  .El
181
181
  .Pp
182
182
  .Sh ENVIRONMENT
183
- .Bl -tag -compact -width "XDG_CONFIG_HOME"
183
+ .Bl -tag -compact -width "IRB_USE_AUTOCOMPLETE"
184
184
  .It Ev IRB_LANG
185
185
  The locale used for
186
186
  .Nm .
@@ -190,10 +190,43 @@ The path to the personal initialization file.
190
190
  .Pp
191
191
  .It Ev XDG_CONFIG_HOME
192
192
  .Nm
193
- respects XDG_CONFIG_HOME. If this is set, load
193
+ respects XDG_CONFIG_HOME. If it is set and
194
+ .Ev IRBRC
195
+ is unset, load
194
196
  .Pa $XDG_CONFIG_HOME/irb/irbrc
195
197
  as a personal initialization file.
196
198
  .Pp
199
+ .It Ev RI_PAGER
200
+ The command specified would be used as a pager.
201
+ .Pp
202
+ .It Ev PAGER
203
+ The command specified would be used as a pager if
204
+ .Ev RI_PAGER
205
+ is unset.
206
+ .Pp
207
+ .It Ev VISUAL
208
+ Its value would be used to open files by the edit command.
209
+ .Pp
210
+ .It Ev EDITOR
211
+ Its value would be used to open files by the edit command if
212
+ .Ev VISUAL
213
+ is unset.
214
+ .Pp
215
+ .It Ev NO_COLOR
216
+ Assigning a value to it disables colorization.
217
+ .Pp
218
+ .It Ev IRB_USE_AUTOCOMPLETE
219
+ Assigning
220
+ .Sy false
221
+ to it disables autocompletion.
222
+ .Pp
223
+ .It Ev IRB_COMPLETOR
224
+ Autocompletion behavior. Allowed values are
225
+ .Sy regexp
226
+ or
227
+ .Sy type
228
+ .
229
+ .Pp
197
230
  .El
198
231
  .Pp
199
232
  Also
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.1
4
+ version: 1.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-09-26 00:00:00.000000000 Z
12
+ date: 2024-12-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: reline