irb 1.14.1 → 1.14.3

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: 7b71e88a4dbaabac4d4a40667f3bd763bd05dfda12832919e44072f04f85ceb4
4
- data.tar.gz: 213f59cc1bc59c61ea2013e81a098d0cb1c95f9972233cb8886bb7b353884fe8
3
+ metadata.gz: 3f1a9b1cbe12db08853604fff0b28f7b66ae1e724d54580ce507e15feb9e0f63
4
+ data.tar.gz: ce18f088328360ab8d39c4c3902984f0110e704b5a6d953e171d8d35c7b545a8
5
5
  SHA512:
6
- metadata.gz: 2ed2dd4b075b7e54ca58bf206c9dca68163564f5bbdbd8bacb24479af62a2b0bbef9d612ae0af0075bda787e189c6020b953c1858e5faecfbab7e9e441d83952
7
- data.tar.gz: 6a81b55c3f04253913c0c1adcc118d61c03cb0b7a5a64410bbfe5495b2fc6d08e0a451eb21302327454f73ef83ed54d74c23ef065139fedbd3a685b1c5562c63
6
+ metadata.gz: a3a46b3c4b9b03dd97175f71cb1a41b02482b996f63b98fa1128c91e741dd17eff1c5af6d314c6756050f4b0e92c398aed1a3ad7adac035d1df0c266e8bd8de0
7
+ data.tar.gz: 57a389d3e32a394e256beb720d9e124f0f48d9bddb26cc8f4913eba2bb7cdd258f30cda97c87cc3bd028f0501d6247a9cbc97eff7279652805d65cdadef67d4c
data/.document CHANGED
@@ -1,4 +1,8 @@
1
1
  LICENSE.txt
2
2
  README.md
3
+ EXTEND_IRB.md
4
+ COMPARED_WITH_PRY.md
3
5
  doc/irb/indexes.md
4
- lib/**/*.rb
6
+ lib/irb.rb
7
+ lib/irb/context.rb
8
+ lib/irb/command/base.rb
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
 
data/Rakefile CHANGED
@@ -46,8 +46,6 @@ task :default => :test
46
46
 
47
47
  RDoc::Task.new do |rdoc|
48
48
  rdoc.title = "IRB"
49
- rdoc.rdoc_files.include("*.md", "lib/**/*.rb")
50
- rdoc.rdoc_files.exclude("lib/irb/xmp.rb")
51
49
  rdoc.rdoc_dir = "docs"
52
50
  rdoc.main = "README.md"
53
51
  rdoc.options.push("--copy-files", "LICENSE.txt")
@@ -5,13 +5,11 @@
5
5
  #
6
6
 
7
7
  module IRB
8
- # :stopdoc:
9
-
10
8
  module Command
11
- class CommandArgumentError < StandardError; end
9
+ class CommandArgumentError < StandardError; end # :nodoc:
12
10
 
13
11
  class << self
14
- def extract_ruby_args(*args, **kwargs)
12
+ def extract_ruby_args(*args, **kwargs) # :nodoc:
15
13
  throw :EXTRACT_RUBY_ARGS, [args, kwargs]
16
14
  end
17
15
  end
@@ -57,8 +55,6 @@ module IRB
57
55
  end
58
56
  end
59
57
 
60
- Nop = Base
58
+ Nop = Base # :nodoc:
61
59
  end
62
-
63
- # :startdoc:
64
60
  end
@@ -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
data/lib/irb/debug.rb CHANGED
@@ -81,6 +81,7 @@ module IRB
81
81
  IRB.instance_variable_set(:@debugger_irb, irb)
82
82
  irb.context.with_debugger = true
83
83
  irb.context.irb_name += ":rdbg"
84
+ irb.context.io.load_history if irb.context.io.class < HistorySavingAbility
84
85
  end
85
86
 
86
87
  module SkipPathHelperForIRB
@@ -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.3"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2024-09-25"
10
+ @LAST_UPDATE_DATE = "2024-12-18"
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"
@@ -74,7 +75,7 @@ require_relative "irb/pager"
74
75
  # 2. Constructs the initial session context from [hash
75
76
  # IRB.conf](rdoc-ref:IRB@Hash+IRB.conf) and from default values; the hash
76
77
  # content may have been affected by [command-line
77
- # options](rdoc-ref:IB@Command-Line+Options), and by direct assignments in
78
+ # options](rdoc-ref:IRB@Command-Line+Options), and by direct assignments in
78
79
  # the configuration file.
79
80
  # 3. Assigns the context to variable `conf`.
80
81
  # 4. Assigns command-line arguments to variable `ARGV`.
@@ -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
@@ -878,7 +879,7 @@ require_relative "irb/pager"
878
879
  module IRB
879
880
 
880
881
  # An exception raised by IRB.irb_abort
881
- class Abort < Exception;end
882
+ class Abort < Exception;end # :nodoc:
882
883
 
883
884
  class << self
884
885
  # The current IRB::Context of the session, see IRB.conf
@@ -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.3
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-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: reline