irb 1.2.7 → 1.2.8

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: 06c24147c0b5bb8af2c024688cee07a8c03ebfa3d804139ea3dc767dbb7a6b72
4
- data.tar.gz: f963948ad72203fec9e8c5cd9d408451718675048c5ca8104fedbdcc34b07483
3
+ metadata.gz: 6ffc4aa655192040fa6afa339ebd3a440a0edab364b8adb43879b46b4437bb7d
4
+ data.tar.gz: b8abfe5e41f5685a487458d6c8dde123151b4e49814850d39bb54ac159614850
5
5
  SHA512:
6
- metadata.gz: eefceccb8108975077b8158a8a8a7e03600e3180b039970e729bc3919b414de18505ac817be670a8c8dd108099ce232d8db06f6dc04a74e1c963e369962df158
7
- data.tar.gz: e5ad1fcece6c08e3d807bead5e63950b1e34f6021ae75c40e647ae94bb075ec9e9b07b92e1665eb873e4397c69ab30d15794520e5ae8b765bb97127cddbaf8db
6
+ metadata.gz: fb7613e840270144cf31aeeffa2ae70367492c79a47dcae24da0ff90c69ca8c089efb031f52972b50be02db816ad4e35a493b654f2a43e7639f1fdf9c55060e7
7
+ data.tar.gz: d587ad70d0d944a7c9f0ca58adff4adf0055d3d1f6aa3052f4d2783cf04f4184689d6e16dff173bddf1755543eedecd4308da6db113aca644502ce4aa46274d3
data/lib/irb.rb CHANGED
@@ -400,7 +400,7 @@ module IRB
400
400
  irb.run(@CONF)
401
401
  end
402
402
 
403
- # Calls each event hook of <code>IRB.conf[:TA_EXIT]</code> when the current session quits.
403
+ # Calls each event hook of <code>IRB.conf[:AT_EXIT]</code> when the current session quits.
404
404
  def IRB.irb_at_exit
405
405
  @CONF[:AT_EXIT].each{|hook| hook.call}
406
406
  end
@@ -538,7 +538,23 @@ module IRB
538
538
  signal_status(:IN_EVAL) do
539
539
  begin
540
540
  line.untaint if RUBY_VERSION < '2.7'
541
- @context.evaluate(line, line_no, exception: exc)
541
+ if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
542
+ IRB.set_measure_callback
543
+ end
544
+ if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
545
+ result = nil
546
+ last_proc = proc{ result = @context.evaluate(line, line_no, exception: exc) }
547
+ IRB.conf[:MEASURE_CALLBACKS].map{ |s| s.last }.inject(last_proc) { |chain, item|
548
+ proc {
549
+ item.(@context, line, line_no, exception: exc) do
550
+ chain.call
551
+ end
552
+ }
553
+ }.call
554
+ @context.set_last_value(result)
555
+ else
556
+ @context.evaluate(line, line_no, exception: exc)
557
+ end
542
558
  if @context.echo?
543
559
  if assignment_expression?(line)
544
560
  if @context.echo_on_assignment?
@@ -761,7 +777,7 @@ module IRB
761
777
  str = "%s...\e[0m" % lines.first
762
778
  multiline_p = false
763
779
  else
764
- str.gsub!(/(\A.*?\n).*/m, "\\1...")
780
+ str = str.gsub(/(\A.*?\n).*/m, "\\1...")
765
781
  end
766
782
  else
767
783
  output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
@@ -16,7 +16,7 @@ module IRB
16
16
  module ExtendCommand
17
17
  class Fork < Nop
18
18
  def execute
19
- pid = send ExtendCommand.irb_original_method_name("fork")
19
+ pid = __send__ ExtendCommand.irb_original_method_name("fork")
20
20
  unless pid
21
21
  class << self
22
22
  alias_method :exit, ExtendCommand.irb_original_method_name('exit')
@@ -268,7 +268,7 @@ module IRB
268
268
  PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
269
269
  RDocRIDriver ||= RDoc::RI::Driver.new
270
270
  if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
271
- IRB.send(:easter_egg)
271
+ IRB.__send__(:easter_egg)
272
272
  return
273
273
  end
274
274
  namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
@@ -126,6 +126,7 @@ module IRB
126
126
  print "\e[H" + buff
127
127
  sleep 0.05
128
128
  end
129
+ rescue Interrupt
129
130
  ensure
130
131
  print "\e[0m\e[?1049l"
131
132
  end
@@ -134,4 +135,4 @@ module IRB
134
135
  end
135
136
  end
136
137
 
137
- IRB.send(:easter_egg, ARGV[0]&.to_sym) if $0 == __FILE__
138
+ IRB.__send__(:easter_egg, ARGV[0]&.to_sym) if $0 == __FILE__
@@ -125,6 +125,10 @@ module IRB # :nodoc:
125
125
  :irb_info, :Info, "irb/cmd/info"
126
126
  ],
127
127
 
128
+ [
129
+ :measure, :Measure, "irb/cmd/measure"
130
+ ],
131
+
128
132
  ]
129
133
 
130
134
  # Installs the default irb commands:
@@ -180,7 +184,7 @@ module IRB # :nodoc:
180
184
  end
181
185
  end
182
186
  ], nil, __FILE__, line
183
- send :#{cmd_name}_, *opts, &b
187
+ __send__ :#{cmd_name}_, *opts, &b
184
188
  end
185
189
  ], nil, __FILE__, line
186
190
  else
@@ -268,7 +272,7 @@ module IRB # :nodoc:
268
272
  def #{cmd_name}(*opts, &b)
269
273
  Context.module_eval {remove_method(:#{cmd_name})}
270
274
  require "#{load_file}"
271
- send :#{cmd_name}, *opts, &b
275
+ __send__ :#{cmd_name}, *opts, &b
272
276
  end
273
277
  for ali in aliases
274
278
  alias_method ali, cmd_name
@@ -291,8 +295,8 @@ module IRB # :nodoc:
291
295
  module_eval %[
292
296
  alias_method alias_name, base_method
293
297
  def #{base_method}(*opts)
294
- send :#{extend_method}, *opts
295
- send :#{alias_name}, *opts
298
+ __send__ :#{extend_method}, *opts
299
+ __send__ :#{alias_name}, *opts
296
300
  end
297
301
  ]
298
302
  end
@@ -307,8 +311,8 @@ module IRB # :nodoc:
307
311
  module_eval %[
308
312
  alias_method alias_name, base_method
309
313
  def #{base_method}(*opts)
310
- send :#{alias_name}, *opts
311
- send :#{extend_method}, *opts
314
+ __send__ :#{alias_name}, *opts
315
+ __send__ :#{extend_method}, *opts
312
316
  end
313
317
  ]
314
318
  end
@@ -108,14 +108,69 @@ module IRB # :nodoc:
108
108
  @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
109
109
  @CONF[:AUTO_INDENT] = true
110
110
 
111
- @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
111
+ @CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING
112
112
  @CONF[:SINGLE_IRB] = false
113
113
 
114
+ @CONF[:MEASURE] = false
115
+ @CONF[:MEASURE_PROC] = {}
116
+ @CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block|
117
+ time = Time.now
118
+ result = block.()
119
+ now = Time.now
120
+ puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
121
+ result
122
+ }
123
+ @CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, &block|
124
+ success = false
125
+ begin
126
+ require 'stackprof'
127
+ success = true
128
+ rescue LoadError
129
+ puts 'Please run "gem install stackprof" before measuring by StackProf.'
130
+ end
131
+ if success
132
+ result = nil
133
+ stackprof_result = StackProf.run(mode: :cpu) do
134
+ result = block.()
135
+ end
136
+ StackProf::Report.new(stackprof_result).print_text if IRB.conf[:MEASURE]
137
+ result
138
+ else
139
+ block.()
140
+ end
141
+ }
142
+ @CONF[:MEASURE_CALLBACKS] = []
143
+
114
144
  @CONF[:LC_MESSAGES] = Locale.new
115
145
 
116
146
  @CONF[:AT_EXIT] = []
117
147
  end
118
148
 
149
+ def IRB.set_measure_callback(type = nil)
150
+ added = nil
151
+ if type
152
+ type_sym = type.upcase.to_sym
153
+ if IRB.conf[:MEASURE_PROC][type_sym]
154
+ added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym]]
155
+ end
156
+ elsif IRB.conf[:MEASURE_PROC][:CUSTOM]
157
+ added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM]]
158
+ else
159
+ added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME]]
160
+ end
161
+ IRB.conf[:MEASURE_CALLBACKS] << added if added
162
+ added
163
+ end
164
+
165
+ def IRB.unset_measure_callback(type = nil)
166
+ if type.nil?
167
+ IRB.conf[:MEASURE_CALLBACKS].clear
168
+ else
169
+ type_sym = type.upcase.to_sym
170
+ IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, c| t == type_sym }
171
+ end
172
+ end
173
+
119
174
  def IRB.init_error
120
175
  @CONF[:LC_MESSAGES].load("irb/error.rb")
121
176
  end
@@ -131,7 +186,7 @@ module IRB # :nodoc:
131
186
  $DEBUG = true
132
187
  $VERBOSE = true
133
188
  when "-w"
134
- $VERBOSE = true
189
+ Warning[:deprecated] = $VERBOSE = true
135
190
  when /^-W(.+)?/
136
191
  opt = $1 || argv.shift
137
192
  case opt
@@ -140,7 +195,7 @@ module IRB # :nodoc:
140
195
  when "1"
141
196
  $VERBOSE = false
142
197
  else
143
- $VERBOSE = true
198
+ Warning[:deprecated] = $VERBOSE = true
144
199
  end
145
200
  when /^-r(.+)?/
146
201
  opt = $1 || argv.shift
@@ -60,11 +60,26 @@ class RubyLex
60
60
  @io.dynamic_prompt do |lines|
61
61
  lines << '' if lines.empty?
62
62
  result = []
63
- lines.each_index { |i|
64
- c = lines[0..i].map{ |l| l + "\n" }.join
65
- ltype, indent, continue, code_block_open = check_state(c)
66
- result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + i)
67
- }
63
+ tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
64
+ code = String.new
65
+ partial_tokens = []
66
+ unprocessed_tokens = []
67
+ line_num_offset = 0
68
+ tokens.each do |t|
69
+ code << t[2]
70
+ partial_tokens << t
71
+ unprocessed_tokens << t
72
+ if t[2].include?("\n")
73
+ ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
74
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
75
+ line_num_offset += 1
76
+ unprocessed_tokens = []
77
+ end
78
+ end
79
+ unless unprocessed_tokens.empty?
80
+ ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens)
81
+ result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
82
+ end
68
83
  result
69
84
  end
70
85
  end
@@ -121,12 +136,12 @@ class RubyLex
121
136
  end
122
137
  end
123
138
 
124
- def check_state(code)
125
- @tokens = ripper_lex_without_warning(code)
126
- ltype = process_literal_type
127
- indent = process_nesting_level
128
- continue = process_continue
129
- code_block_open = check_code_block(code)
139
+ def check_state(code, tokens = nil)
140
+ tokens = ripper_lex_without_warning(code) unless tokens
141
+ ltype = process_literal_type(tokens)
142
+ indent = process_nesting_level(tokens)
143
+ continue = process_continue(tokens)
144
+ code_block_open = check_code_block(code, tokens)
130
145
  [ltype, indent, continue, code_block_open]
131
146
  end
132
147
 
@@ -186,47 +201,52 @@ class RubyLex
186
201
  code = @line + (line.nil? ? '' : line)
187
202
  code.gsub!(/\s*\z/, '').concat("\n")
188
203
  @tokens = ripper_lex_without_warning(code)
189
- @continue = process_continue
190
- @code_block_open = check_code_block(code)
191
- @indent = process_nesting_level
192
- @ltype = process_literal_type
204
+ @continue = process_continue(@tokens)
205
+ @code_block_open = check_code_block(code, @tokens)
206
+ @indent = process_nesting_level(@tokens)
207
+ @ltype = process_literal_type(@tokens)
193
208
  line
194
209
  end
195
210
 
196
- def process_continue
211
+ def process_continue(tokens)
197
212
  # last token is always newline
198
- if @tokens.size >= 2 and @tokens[-2][1] == :on_regexp_end
213
+ if tokens.size >= 2 and tokens[-2][1] == :on_regexp_end
199
214
  # end of regexp literal
200
215
  return false
201
- elsif @tokens.size >= 2 and @tokens[-2][1] == :on_semicolon
216
+ elsif tokens.size >= 2 and tokens[-2][1] == :on_semicolon
202
217
  return false
203
- elsif @tokens.size >= 2 and @tokens[-2][1] == :on_kw and ['begin', 'else', 'ensure'].include?(@tokens[-2][2])
218
+ elsif tokens.size >= 2 and tokens[-2][1] == :on_kw and ['begin', 'else', 'ensure'].include?(tokens[-2][2])
204
219
  return false
205
- elsif !@tokens.empty? and @tokens.last[2] == "\\\n"
220
+ elsif !tokens.empty? and tokens.last[2] == "\\\n"
206
221
  return true
207
- elsif @tokens.size >= 1 and @tokens[-1][1] == :on_heredoc_end # "EOH\n"
222
+ elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
208
223
  return false
209
- elsif @tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and @tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
224
+ elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
210
225
  # end of literal except for regexp
211
226
  return true
212
227
  end
213
228
  false
214
229
  end
215
230
 
216
- def check_code_block(code)
217
- return true if @tokens.empty?
218
- if @tokens.last[1] == :on_heredoc_beg
231
+ def check_code_block(code, tokens)
232
+ return true if tokens.empty?
233
+ if tokens.last[1] == :on_heredoc_beg
219
234
  return true
220
235
  end
221
236
 
222
237
  begin # check if parser error are available
223
238
  verbose, $VERBOSE = $VERBOSE, nil
224
239
  case RUBY_ENGINE
240
+ when 'ruby'
241
+ self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
242
+ RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
243
+ end
225
244
  when 'jruby'
226
245
  JRuby.compile_ir(code)
227
246
  else
228
- self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
229
- RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no)
247
+ catch(:valid) do
248
+ eval("BEGIN { throw :valid, true }\n#{code}")
249
+ false
230
250
  end
231
251
  end
232
252
  rescue EncodingError
@@ -282,7 +302,7 @@ class RubyLex
282
302
  end
283
303
 
284
304
  if defined?(Ripper::EXPR_BEG)
285
- last_lex_state = @tokens.last[3]
305
+ last_lex_state = tokens.last[3]
286
306
  if last_lex_state.allbits?(Ripper::EXPR_BEG)
287
307
  return false
288
308
  elsif last_lex_state.allbits?(Ripper::EXPR_DOT)
@@ -301,10 +321,10 @@ class RubyLex
301
321
  false
302
322
  end
303
323
 
304
- def process_nesting_level
324
+ def process_nesting_level(tokens)
305
325
  indent = 0
306
326
  in_oneliner_def = nil
307
- @tokens.each_with_index { |t, index|
327
+ tokens.each_with_index { |t, index|
308
328
  # detecting one-liner method definition
309
329
  if in_oneliner_def.nil?
310
330
  if t[3].allbits?(Ripper::EXPR_ENDFN)
@@ -317,14 +337,12 @@ class RubyLex
317
337
  if t[2] == '='
318
338
  in_oneliner_def = :BODY
319
339
  end
320
- elsif t[3].allbits?(Ripper::EXPR_END)
340
+ else
321
341
  if in_oneliner_def == :BODY
322
342
  # one-liner method definition
323
343
  indent -= 1
324
344
  end
325
345
  in_oneliner_def = nil
326
- else
327
- in_oneliner_def = nil
328
346
  end
329
347
  end
330
348
 
@@ -334,10 +352,10 @@ class RubyLex
334
352
  when :on_rbracket, :on_rbrace, :on_rparen
335
353
  indent -= 1
336
354
  when :on_kw
337
- next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
355
+ next if index > 0 and tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
338
356
  case t[2]
339
357
  when 'do'
340
- if index > 0 and @tokens[index - 1][3].anybits?(Ripper::EXPR_CMDARG | Ripper::EXPR_ENDFN | Ripper::EXPR_ARG)
358
+ if index > 0 and tokens[index - 1][3].anybits?(Ripper::EXPR_CMDARG | Ripper::EXPR_ENDFN | Ripper::EXPR_ARG)
341
359
  # method_with_block do; end
342
360
  indent += 1
343
361
  else
@@ -376,14 +394,12 @@ class RubyLex
376
394
  if t[2] == '='
377
395
  in_oneliner_def = :BODY
378
396
  end
379
- elsif t[3].allbits?(Ripper::EXPR_END)
397
+ else
380
398
  if in_oneliner_def == :BODY
381
- # one[-liner method definition
399
+ # one-liner method definition
382
400
  depth_difference -= 1
383
401
  end
384
402
  in_oneliner_def = nil
385
- else
386
- in_oneliner_def = nil
387
403
  end
388
404
  end
389
405
 
@@ -451,7 +467,7 @@ class RubyLex
451
467
  if t[2] == '='
452
468
  in_oneliner_def = :BODY
453
469
  end
454
- elsif t[3].allbits?(Ripper::EXPR_END)
470
+ else
455
471
  if in_oneliner_def == :BODY
456
472
  # one-liner method definition
457
473
  if is_first_printable_of_line
@@ -462,8 +478,6 @@ class RubyLex
462
478
  end
463
479
  end
464
480
  in_oneliner_def = nil
465
- else
466
- in_oneliner_def = nil
467
481
  end
468
482
  end
469
483
 
@@ -523,12 +537,12 @@ class RubyLex
523
537
  corresponding_token_depth
524
538
  end
525
539
 
526
- def check_string_literal
540
+ def check_string_literal(tokens)
527
541
  i = 0
528
542
  start_token = []
529
543
  end_type = []
530
- while i < @tokens.size
531
- t = @tokens[i]
544
+ while i < tokens.size
545
+ t = tokens[i]
532
546
  case t[1]
533
547
  when :on_tstring_beg
534
548
  start_token << t
@@ -538,7 +552,7 @@ class RubyLex
538
552
  end_type << :on_regexp_end
539
553
  when :on_symbeg
540
554
  acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw}
541
- if (i + 1) < @tokens.size and acceptable_single_tokens.all?{ |t| @tokens[i + 1][1] != t }
555
+ if (i + 1) < tokens.size and acceptable_single_tokens.all?{ |t| tokens[i + 1][1] != t }
542
556
  start_token << t
543
557
  end_type << :on_tstring_end
544
558
  end
@@ -560,8 +574,8 @@ class RubyLex
560
574
  start_token.last.nil? ? '' : start_token.last
561
575
  end
562
576
 
563
- def process_literal_type
564
- start_token = check_string_literal
577
+ def process_literal_type(tokens)
578
+ start_token = check_string_literal(tokens)
565
579
  case start_token[1]
566
580
  when :on_tstring_beg
567
581
  case start_token[2]
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.2.7"
14
+ VERSION = "1.2.8"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2020-09-19"
16
+ @LAST_UPDATE_DATE = "2020-12-20"
17
17
  end
@@ -51,11 +51,13 @@ EOF
51
51
  end
52
52
  @binding = BINDING_QUEUE.pop
53
53
 
54
- when 3 # binding in function on TOPLEVEL_BINDING(default)
55
- @binding = eval("self.class.send(:remove_method, :irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
54
+ when 3 # binding in function on TOPLEVEL_BINDING
55
+ @binding = eval("self.class.remove_method(:irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
56
56
  TOPLEVEL_BINDING,
57
57
  __FILE__,
58
58
  __LINE__ - 3)
59
+ when 4 # binding is a copy of TOPLEVEL_BINDING (default)
60
+ @binding = TOPLEVEL_BINDING.dup
59
61
  end
60
62
  end
61
63
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keiju ISHITSUKA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-18 00:00:00.000000000 Z
11
+ date: 2020-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reline
@@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
134
  - !ruby/object:Gem::Version
135
135
  version: '0'
136
136
  requirements: []
137
- rubygems_version: 3.1.2
137
+ rubygems_version: 3.1.4
138
138
  signing_key:
139
139
  specification_version: 4
140
140
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).