irb 1.2.7 → 1.2.8

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: 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).