irb 1.9.0 → 1.10.0

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: 810aa12a1fbfdbd0ff9f9c4d5c4ac71e62e8241f87cb1a306be1ff81aaef08cb
4
- data.tar.gz: 781d169232ac355b9723e8dc03d6c0de4c16327b4a4a3339cd1e90bad7e1c0b1
3
+ metadata.gz: c0e7153fbd64c519a7af411d95779821c279a63b786c16df0e5cff4b577a258f
4
+ data.tar.gz: 86c81569fa9788676c575f64b1010191690b4b3c056330e5f21fb798d724924f
5
5
  SHA512:
6
- metadata.gz: 51d97e80d977c6ce100f66cc0ad4becae17600d36653be88cc7c2f1e6cd0b7127cec01344bc69b04de1b043f8d45a1d07f6b4b8ad3fad4584585aca269cfa65f
7
- data.tar.gz: a197cf8c07a1ea728a3c9d0d70fdd28a2a5b9a4e9ebf72a8fd8d6495627cf4c369e6831879a766c5dd8819438bb1f126b0d4d669becc4c63a7ad6c4ea51a3a79
6
+ metadata.gz: e78e35a1a46ac5b4e62e93f7cac0e1b3657b16cd108851624b3cfd2b6c81662ca6dfa7aff9737d743a625eaa96a47179c95e9af28833dcb9d761ee150923497d
7
+ data.tar.gz: 562c5e88c5c09adbe4f882d30a34b496599af4f7a45f41d60609ef91148d7271cd97bbfd629ca75da4f3845d7815e51bca3b1969e9bff1c723c18b3c0840517d
data/Gemfile CHANGED
@@ -16,11 +16,9 @@ gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true"
16
16
  gem "rake"
17
17
  gem "test-unit"
18
18
  gem "test-unit-ruby-core"
19
- gem "debug", github: "ruby/debug"
20
19
 
21
- gem "racc"
20
+ gem "debug", github: "ruby/debug", platforms: [:mri, :mswin]
22
21
 
23
- if RUBY_VERSION >= "3.0.0"
24
- gem "rbs"
25
- gem "prism", ">= 0.17.1"
22
+ if RUBY_VERSION >= "3.0.0" && !is_truffleruby
23
+ gem "repl_type_completor"
26
24
  end
data/README.md CHANGED
@@ -119,6 +119,7 @@ IRB
119
119
  source Loads a given file in the current session.
120
120
  irb_info Show information about IRB.
121
121
  show_cmds List all available commands and their description.
122
+ history Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output.
122
123
 
123
124
  Multi-irb (DEPRECATED)
124
125
  irb Start a child IRB.
@@ -237,11 +238,11 @@ However, there are also some limitations to be aware of:
237
238
 
238
239
  ## Type Based Completion
239
240
 
240
- IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletion` that uses type analysis.
241
+ IRB's default completion `IRB::RegexpCompletor` uses Regexp. IRB has another experimental completion `IRB::TypeCompletor` that uses type analysis.
241
242
 
242
- ### How to Enable IRB::TypeCompletion
243
+ ### How to Enable IRB::TypeCompletor
243
244
 
244
- To enable IRB::TypeCompletion, run IRB with `--type-completor` option
245
+ To enable IRB::TypeCompletor, run IRB with `--type-completor` option
245
246
  ```
246
247
  $ irb --type-completor
247
248
  ```
@@ -249,14 +250,14 @@ Or write the code below to IRB's rc-file.
249
250
  ```ruby
250
251
  IRB.conf[:COMPLETOR] = :type # default is :regexp
251
252
  ```
252
- You also need `gem prism` and `gem rbs` to use this feature.
253
+ You also need `gem repl_type_completor` to use this feature.
253
254
 
254
255
  To check if it's enabled, type `irb_info` into IRB and see the `Completion` section.
255
256
  ```
256
257
  irb(main):001> irb_info
257
258
  ...
258
259
  # Enabled
259
- Completion: Autocomplete, TypeCompletion::Completor(Prism: 0.17.1, RBS: 3.3.0)
260
+ Completion: Autocomplete, ReplTypeCompletor: 0.1.0, Prism: 0.18.0, RBS: 3.3.0
260
261
  # Not enabled
261
262
  Completion: Autocomplete, RegexpCompletor
262
263
  ...
@@ -265,7 +266,7 @@ If you have `sig/` directory or `rbs_collection.lock.yaml` in current directory,
265
266
 
266
267
  ### Advantage over Default IRB::RegexpCompletor
267
268
 
268
- IRB::TypeCompletion can autocomplete chained methods, block parameters and more if type information is available.
269
+ IRB::TypeCompletor can autocomplete chained methods, block parameters and more if type information is available.
269
270
  These are some examples IRB::RegexpCompletor cannot complete.
270
271
 
271
272
  ```ruby
@@ -287,11 +288,11 @@ As a trade-off, completion calculation takes more time than IRB::RegexpCompletor
287
288
 
288
289
  ### Difference between Steep's Completion
289
290
 
290
- Compared with Steep, IRB::TypeCompletion has some difference and limitations.
291
+ Compared with Steep, IRB::TypeCompletor has some difference and limitations.
291
292
  ```ruby
292
293
  [0, 'a'].sample.
293
294
  # Steep completes intersection of Integer methods and String methods
294
- # IRB::TypeCompletion completes both Integer and String methods
295
+ # IRB::TypeCompletor completes both Integer and String methods
295
296
  ```
296
297
 
297
298
  Some features like type narrowing is not implemented.
@@ -301,7 +302,7 @@ def f(arg = [0, 'a'].sample)
301
302
  arg. # Completes both Integer and String methods
302
303
  ```
303
304
 
304
- Unlike other static type checker, IRB::TypeCompletion uses runtime information to provide better completion.
305
+ Unlike other static type checker, IRB::TypeCompletor uses runtime information to provide better completion.
305
306
  ```ruby
306
307
  irb(main):001> a = [1]
307
308
  => [1]
@@ -314,6 +315,7 @@ irb(main):002> a.first. # Completes Integer methods
314
315
 
315
316
  - `NO_COLOR`: Assigning a value to it disables IRB's colorization.
316
317
  - `IRB_USE_AUTOCOMPLETE`: Setting it to `false` disables IRB's autocompletion.
318
+ - `IRB_COMPLETOR`: Configures IRB's auto-completion behavior, allowing settings for either `regexp` or `type`.
317
319
  - `VISUAL`: Its value would be used to open files by the `edit` command.
318
320
  - `EDITOR`: Its value would be used to open files by the `edit` command if `VISUAL` is unset.
319
321
  - `IRBRC`: The file specified would be evaluated as IRB's rc-file.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test" << "test/lib"
6
6
  t.libs << "lib"
7
7
  t.ruby_opts << "-rhelper"
8
- t.test_files = FileList["test/irb/test_*.rb", "test/irb/type_completion/test_*.rb"]
8
+ t.test_files = FileList["test/irb/**/test_*.rb"]
9
9
  end
10
10
 
11
11
  # To make sure they have been correctly setup for Ruby CI.
@@ -13,7 +13,7 @@ desc "Run each irb test file in isolation."
13
13
  task :test_in_isolation do
14
14
  failed = false
15
15
 
16
- FileList["test/irb/test_*.rb", "test/irb/type_completion/test_*.rb"].each do |test_file|
16
+ FileList["test/irb/**/test_*.rb"].each do |test_file|
17
17
  ENV["TEST"] = test_file
18
18
  begin
19
19
  Rake::Task["test"].execute
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+ require_relative "nop"
5
+ require_relative "../pager"
6
+
7
+ module IRB
8
+ # :stopdoc:
9
+
10
+ module ExtendCommand
11
+ class History < Nop
12
+ category "IRB"
13
+ description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output."
14
+
15
+ def self.transform_args(args)
16
+ match = args&.match(/(-g|-G)\s+(?<grep>.+)\s*\n\z/)
17
+ return unless match
18
+
19
+ "grep: #{Regexp.new(match[:grep]).inspect}"
20
+ end
21
+
22
+ def execute(grep: nil)
23
+ formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index|
24
+ next if grep && !input.match?(grep)
25
+
26
+ header = "#{index}: "
27
+
28
+ first_line, *other_lines = input.split("\n")
29
+ first_line = "#{header}#{first_line}"
30
+
31
+ truncated_lines = other_lines.slice!(1..) # Show 1 additional line (2 total)
32
+ other_lines << "..." if truncated_lines&.any?
33
+
34
+ other_lines.map! do |line|
35
+ " " * header.length + line
36
+ end
37
+
38
+ [first_line, *other_lines].join("\n") + "\n"
39
+ end
40
+
41
+ Pager.page_content(formatted_inputs.join)
42
+ end
43
+ end
44
+ end
45
+
46
+ # :startdoc:
47
+ end
@@ -16,6 +16,12 @@ module IRB
16
16
  commands_info = IRB::ExtendCommandBundle.all_commands_info
17
17
  commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
18
18
 
19
+ user_aliases = irb_context.instance_variable_get(:@user_aliases)
20
+
21
+ commands_grouped_by_categories["Aliases"] = user_aliases.map do |alias_name, target|
22
+ { display_name: alias_name, description: "Alias for `#{target}`" }
23
+ end
24
+
19
25
  if irb_context.with_debugger
20
26
  # Remove the original "Debugging" category
21
27
  commands_grouped_by_categories.delete("Debugging")
@@ -27,11 +27,18 @@ module IRB
27
27
  puts "Error: Expected a string but got #{str.inspect}"
28
28
  return
29
29
  end
30
-
31
- source = SourceFinder.new(@irb_context).find_source(str)
30
+ if str.include? " -s"
31
+ str, esses = str.split(" -")
32
+ s_count = esses.count("^s").zero? ? esses.size : 1
33
+ source = SourceFinder.new(@irb_context).find_source(str, s_count)
34
+ else
35
+ source = SourceFinder.new(@irb_context).find_source(str)
36
+ end
32
37
 
33
38
  if source
34
39
  show_source(source)
40
+ elsif s_count
41
+ puts "Error: Couldn't locate a super definition for #{str}"
35
42
  else
36
43
  puts "Error: Couldn't locate a definition for #{str}"
37
44
  end
@@ -93,6 +93,27 @@ module IRB
93
93
  end
94
94
  end
95
95
 
96
+ class TypeCompletor < BaseCompletor # :nodoc:
97
+ def initialize(context)
98
+ @context = context
99
+ end
100
+
101
+ def inspect
102
+ ReplTypeCompletor.info
103
+ end
104
+
105
+ def completion_candidates(preposing, target, _postposing, bind:)
106
+ result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
107
+ return [] unless result
108
+ result.completion_candidates.map { target + _1 }
109
+ end
110
+
111
+ def doc_namespace(preposing, matched, _postposing, bind:)
112
+ result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
113
+ result&.doc_namespace('')
114
+ end
115
+ end
116
+
96
117
  class RegexpCompletor < BaseCompletor # :nodoc:
97
118
  using Module.new {
98
119
  refine ::Binding do
@@ -210,16 +231,16 @@ module IRB
210
231
  end
211
232
 
212
233
  when /^([^\}]*\})\.([^.]*)$/
213
- # Proc or Hash
234
+ # Hash or Proc
214
235
  receiver = $1
215
236
  message = $2
216
237
 
217
238
  if doc_namespace
218
- ["Proc.#{message}", "Hash.#{message}"]
239
+ ["Hash.#{message}", "Proc.#{message}"]
219
240
  else
220
- proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
221
241
  hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
222
- select_message(receiver, message, proc_candidates | hash_candidates)
242
+ proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
243
+ select_message(receiver, message, hash_candidates | proc_candidates)
223
244
  end
224
245
 
225
246
  when /^(:[^:.]+)$/
data/lib/irb/context.rb CHANGED
@@ -146,9 +146,21 @@ module IRB
146
146
  @newline_before_multiline_output = true
147
147
  end
148
148
 
149
- @command_aliases = IRB.conf[:COMMAND_ALIASES]
149
+ @user_aliases = IRB.conf[:COMMAND_ALIASES].dup
150
+ @command_aliases = @user_aliases.merge(KEYWORD_ALIASES)
150
151
  end
151
152
 
153
+ # because all input will eventually be evaluated as Ruby code,
154
+ # command names that conflict with Ruby keywords need special workaround
155
+ # we can remove them once we implemented a better command system for IRB
156
+ KEYWORD_ALIASES = {
157
+ :break => :irb_break,
158
+ :catch => :irb_catch,
159
+ :next => :irb_next,
160
+ }.freeze
161
+
162
+ private_constant :KEYWORD_ALIASES
163
+
152
164
  private def build_completor
153
165
  completor_type = IRB.conf[:COMPLETOR]
154
166
  case completor_type
@@ -164,26 +176,22 @@ module IRB
164
176
  RegexpCompletor.new
165
177
  end
166
178
 
167
- TYPE_COMPLETION_REQUIRED_PRISM_VERSION = '0.17.1'
168
-
169
179
  private def build_type_completor
170
- unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') && RUBY_ENGINE != 'truffleruby'
171
- warn 'TypeCompletion requires RUBY_VERSION >= 3.0.0'
180
+ if RUBY_ENGINE == 'truffleruby'
181
+ # Avoid SynatxError. truffleruby does not support endless method definition yet.
182
+ warn 'TypeCompletor is not supported on TruffleRuby yet'
172
183
  return
173
184
  end
185
+
174
186
  begin
175
- require 'prism'
187
+ require 'repl_type_completor'
176
188
  rescue LoadError => e
177
- warn "TypeCompletion requires Prism: #{e.message}"
189
+ warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}"
178
190
  return
179
191
  end
180
- unless Gem::Version.new(Prism::VERSION) >= Gem::Version.new(TYPE_COMPLETION_REQUIRED_PRISM_VERSION)
181
- warn "TypeCompletion requires Prism::VERSION >= #{TYPE_COMPLETION_REQUIRED_PRISM_VERSION}"
182
- return
183
- end
184
- require 'irb/type_completion/completor'
185
- TypeCompletion::Types.preload_in_thread
186
- TypeCompletion::Completor.new
192
+
193
+ ReplTypeCompletor.preload_rbs
194
+ TypeCompletor.new(self)
187
195
  end
188
196
 
189
197
  def save_history=(val)
data/lib/irb/debug.rb CHANGED
@@ -57,6 +57,24 @@ module IRB
57
57
  DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB)
58
58
  end
59
59
 
60
+ if !@output_modifier_defined && !DEBUGGER__::CONFIG[:no_hint]
61
+ irb_output_modifier_proc = Reline.output_modifier_proc
62
+
63
+ Reline.output_modifier_proc = proc do |output, complete:|
64
+ unless output.strip.empty?
65
+ cmd = output.split(/\s/, 2).first
66
+
67
+ if !complete && DEBUGGER__.commands.key?(cmd)
68
+ output = output.sub(/\n$/, " # debug command\n")
69
+ end
70
+ end
71
+
72
+ irb_output_modifier_proc.call(output, complete: complete)
73
+ end
74
+
75
+ @output_modifier_defined = true
76
+ end
77
+
60
78
  true
61
79
  end
62
80
 
@@ -191,6 +191,12 @@ module IRB # :nodoc:
191
191
  [
192
192
  :irb_show_cmds, :ShowCmds, "cmd/show_cmds",
193
193
  [:show_cmds, NO_OVERRIDE],
194
+ ],
195
+
196
+ [
197
+ :irb_history, :History, "cmd/history",
198
+ [:history, NO_OVERRIDE],
199
+ [:hist, NO_OVERRIDE],
194
200
  ]
195
201
  ]
196
202
 
data/lib/irb/history.rb CHANGED
@@ -60,7 +60,7 @@ module IRB
60
60
  end
61
61
 
62
62
  File.open(history_file, (append_history ? 'a' : 'w'), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
63
- hist = history.map{ |l| l.split("\n").join("\\\n") }
63
+ hist = history.map{ |l| l.scrub.split("\n").join("\\\n") }
64
64
  unless append_history
65
65
  begin
66
66
  hist = hist.last(num) if hist.size > num and num > 0
data/lib/irb/init.rb CHANGED
@@ -76,12 +76,13 @@ module IRB # :nodoc:
76
76
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
77
77
  @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
78
78
  @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
79
- @CONF[:COMPLETOR] = :regexp
79
+ @CONF[:COMPLETOR] = ENV.fetch("IRB_COMPLETOR", "regexp").to_sym
80
80
  @CONF[:INSPECT_MODE] = true
81
81
  @CONF[:USE_TRACER] = false
82
82
  @CONF[:USE_LOADER] = false
83
83
  @CONF[:IGNORE_SIGINT] = true
84
84
  @CONF[:IGNORE_EOF] = false
85
+ @CONF[:USE_PAGER] = true
85
86
  @CONF[:EXTRA_DOC_DIRS] = []
86
87
  @CONF[:ECHO] = nil
87
88
  @CONF[:ECHO_ON_ASSIGNMENT] = nil
@@ -188,10 +189,6 @@ module IRB # :nodoc:
188
189
  # Symbol aliases
189
190
  :'$' => :show_source,
190
191
  :'@' => :whereami,
191
- # Keyword aliases
192
- :break => :irb_break,
193
- :catch => :irb_catch,
194
- :next => :irb_next,
195
192
  }
196
193
  end
197
194
 
@@ -285,6 +282,8 @@ module IRB # :nodoc:
285
282
  end
286
283
  when "--noinspect"
287
284
  @CONF[:INSPECT_MODE] = false
285
+ when "--no-pager"
286
+ @CONF[:USE_PAGER] = false
288
287
  when "--singleline", "--readline", "--legacy"
289
288
  @CONF[:USE_SINGLELINE] = true
290
289
  when "--nosingleline", "--noreadline"
@@ -312,6 +312,9 @@ module IRB
312
312
  return nil if result.nil? or pointer.nil? or pointer < 0
313
313
 
314
314
  name = doc_namespace.call(result[pointer])
315
+ # Use first one because document dialog does not support multiple namespaces.
316
+ name = name.first if name.is_a?(Array)
317
+
315
318
  show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
316
319
 
317
320
  options = {}
@@ -22,6 +22,7 @@ Usage: irb.rb [options] [programfile] [arguments]
22
22
  Show truncated result on assignment (default).
23
23
  --inspect Use 'inspect' for output.
24
24
  --noinspect Don't use 'inspect' for output.
25
+ --no-pager Don't use pager.
25
26
  --multiline Use multiline editor module (default).
26
27
  --nomultiline Don't use multiline editor module.
27
28
  --singleline Use single line editor module.
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 IRB.conf[:USE_PAGER] && STDIN.tty? && pager = setup_pager(retain_content: retain_content)
22
22
  begin
23
23
  pid = pager.pid
24
24
  yield pager
@@ -55,19 +55,20 @@ module IRB
55
55
  pageable_height * screen_width < Reline::Unicode.calculate_width(content, true)
56
56
  end
57
57
 
58
- def setup_pager
58
+ def setup_pager(retain_content:)
59
59
  require 'shellwords'
60
60
 
61
- PAGE_COMMANDS.each do |pager|
62
- pager = Shellwords.split(pager)
63
- next if pager.empty?
61
+ PAGE_COMMANDS.each do |pager_cmd|
62
+ cmd = Shellwords.split(pager_cmd)
63
+ next if cmd.empty?
64
64
 
65
- if pager.first == 'less' || pager.first == 'more'
66
- pager << '-R' unless pager.include?('-R')
65
+ if cmd.first == 'less'
66
+ cmd << '-R' unless cmd.include?('-R')
67
+ cmd << '-X' if retain_content && !cmd.include?('-X')
67
68
  end
68
69
 
69
70
  begin
70
- io = IO.popen(pager, 'w')
71
+ io = IO.popen(cmd, 'w')
71
72
  rescue
72
73
  next
73
74
  end
@@ -16,7 +16,7 @@ module IRB
16
16
  @irb_context = irb_context
17
17
  end
18
18
 
19
- def find_source(signature)
19
+ def find_source(signature, s_count = nil)
20
20
  context_binding = @irb_context.workspace.binding
21
21
  case signature
22
22
  when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
@@ -26,14 +26,13 @@ module IRB
26
26
  when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
27
27
  owner = eval(Regexp.last_match[:owner], context_binding)
28
28
  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
29
+ return unless owner.respond_to?(:instance_method)
30
+ file, line = method_target(owner, s_count, method, "owner")
33
31
  when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
34
32
  receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding)
35
33
  method = Regexp.last_match[:method]
36
- file, line = receiver.method(method).source_location if receiver.respond_to?(method, true)
34
+ return unless receiver.respond_to?(method, true)
35
+ file, line = method_target(receiver, s_count, method, "receiver")
37
36
  end
38
37
  if file && line && File.exist?(file)
39
38
  Source.new(file: file, first_line: line, last_line: find_end(file, line))
@@ -60,5 +59,26 @@ module IRB
60
59
  end
61
60
  first_line
62
61
  end
62
+
63
+ def method_target(owner_receiver, s_count, method, type)
64
+ case type
65
+ when "owner"
66
+ target_method = owner_receiver.instance_method(method)
67
+ return target_method.source_location unless s_count
68
+ when "receiver"
69
+ if s_count
70
+ target_method = owner_receiver.class.instance_method(method)
71
+ else
72
+ target_method = method
73
+ return owner_receiver.method(method).source_location
74
+ end
75
+ end
76
+ s_count.times do |s|
77
+ target_method = target_method.super_method if target_method
78
+ end
79
+ target_method.nil? ? nil : target_method.source_location
80
+ rescue NameError
81
+ nil
82
+ end
63
83
  end
64
84
  end
data/lib/irb/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.9.0"
8
+ VERSION = "1.10.0"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2023-11-11"
10
+ @LAST_UPDATE_DATE = "2023-12-03"
11
11
  end