irb 1.1.0.pre.2 → 1.1.0.pre.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: 81da8e8b11979aca60cc0806c7a679f8a854a2f9f38d215f714d377aaac579ae
4
- data.tar.gz: 05f6c327f9226f5789498c182c5b5c4cfe2ada443f65fc3daa577c76e5dcad8e
3
+ metadata.gz: 71eba1b800fb1d93376272f2f222979ae70d21f19a129b9c06a148784a2e178b
4
+ data.tar.gz: 02e1cb9a9d88a5e582467975edf596e848e7076066ada250798c43ccbafdfe0b
5
5
  SHA512:
6
- metadata.gz: 5ab9d21b32e138399ac7eafee532f15f07b85dadc0acb35eb1cd41814a000cb74c69f98455d90b2f7930d23eb79d708468387dcc5b5efb82ac866720e7227cbe
7
- data.tar.gz: 2d2836d6c47a4040c7e8b27442b504e9eced9ffd6c2169f7d50dd5439b6534c6f477d51ffa5f5b14fa02c3cecd0f400b9ea8762d399db0d81532b65b2af3ce62
6
+ metadata.gz: a4acfeb73e0b972fb9ca65b89e1e74f8c9523c26b3d9021af148214f7991d4eb9d633b58a6dbd7b7da7b1c800efc7dd814ddee9bd31c0680ee6e59c0c7b4e5b4
7
+ data.tar.gz: c0cf5a8bf14b9d1fc037021cff5cd6ad94834595b4c21f933367111114a241279c7643db6e1e0ac408746c448ff9f9b37acf65923600e1437a4a77aca07d5f49
data/README.md CHANGED
@@ -31,9 +31,9 @@ $ irb
31
31
  irb(main):001:0> 1+2
32
32
  #=> 3
33
33
  irb(main):002:0> class Foo
34
- irb(main):003:1> def foo
35
- irb(main):004:2> print 1
36
- irb(main):005:2> end
34
+ irb(main):003:1> def foo
35
+ irb(main):004:2> print 1
36
+ irb(main):005:2> end
37
37
  irb(main):006:1> end
38
38
  #=> nil
39
39
  ```
@@ -21,6 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4")
25
+
24
26
  spec.add_dependency "reline", ">= 0.0.1"
25
27
  spec.add_development_dependency "bundler"
26
28
  spec.add_development_dependency "rake"
data/lib/irb.rb CHANGED
@@ -10,6 +10,7 @@
10
10
  #
11
11
  #
12
12
  require "e2mmap"
13
+ require "ripper"
13
14
 
14
15
  require "irb/init"
15
16
  require "irb/context"
@@ -410,6 +411,35 @@ module IRB
410
411
  end
411
412
 
412
413
  class Irb
414
+ ASSIGNMENT_NODE_TYPES = [
415
+ # Local, instance, global, class, constant, instance, and index assignment:
416
+ # "foo = bar",
417
+ # "@foo = bar",
418
+ # "$foo = bar",
419
+ # "@@foo = bar",
420
+ # "::Foo = bar",
421
+ # "a::Foo = bar",
422
+ # "Foo = bar"
423
+ # "foo.bar = 1"
424
+ # "foo[1] = bar"
425
+ :assign,
426
+
427
+ # Operation assignment:
428
+ # "foo += bar"
429
+ # "foo -= bar"
430
+ # "foo ||= bar"
431
+ # "foo &&= bar"
432
+ :opassign,
433
+
434
+ # Multiple assignment:
435
+ # "foo, bar = 1, 2
436
+ :massign,
437
+ ]
438
+ # Note: instance and index assignment expressions could also be written like:
439
+ # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former
440
+ # be parsed as :assign and echo will be suppressed, but the latter is
441
+ # parsed as a :method_add_arg and the output won't be suppressed
442
+
413
443
  # Creates a new irb session
414
444
  def initialize(workspace = nil, input_method = nil, output_method = nil)
415
445
  @context = Context.new(self, workspace, input_method, output_method)
@@ -498,7 +528,7 @@ module IRB
498
528
  begin
499
529
  line.untaint
500
530
  @context.evaluate(line, line_no, exception: exc)
501
- output_value if @context.echo?
531
+ output_value if @context.echo? && (@context.echo_on_assignment? || !assignment_expression?(line))
502
532
  rescue Interrupt => exc
503
533
  rescue SystemExit, SignalException
504
534
  raise
@@ -717,6 +747,18 @@ module IRB
717
747
  format("#<%s: %s>", self.class, ary.join(", "))
718
748
  end
719
749
 
750
+ def assignment_expression?(line)
751
+ # Try to parse the line and check if the last of possibly multiple
752
+ # expressions is an assignment type.
753
+
754
+ # If the expression is invalid, Ripper.sexp should return nil which will
755
+ # result in false being returned. Any valid expression should return an
756
+ # s-expression where the second selement of the top level array is an
757
+ # array of parsed expressions. The first element of each expression is the
758
+ # expression's type.
759
+ ASSIGNMENT_NODE_TYPES.include?(Ripper.sexp(line)&.dig(1,-1,0))
760
+ end
761
+
720
762
  ATTR_TTY = "\e[%sm"
721
763
  def ATTR_TTY.[](*a) self % a.join(";"); end
722
764
  ATTR_PLAIN = ""
@@ -805,7 +847,7 @@ class Binding
805
847
  #
806
848
  # See IRB@IRB+Usage for more information.
807
849
  def irb
808
- IRB.setup(eval("__FILE__"), argv: [])
850
+ IRB.setup(source_location[0], argv: [])
809
851
  workspace = IRB::WorkSpace.new(self)
810
852
  STDOUT.print(workspace.code_around_binding)
811
853
  IRB::Irb.new(workspace).run(IRB.conf)
@@ -205,7 +205,7 @@ module IRB
205
205
  sep = $2
206
206
  message = Regexp.quote($3)
207
207
 
208
- gv = eval("global_variables", bind).collect{|m| m.to_s}
208
+ gv = eval("global_variables", bind).collect{|m| m.to_s}.append("true", "false", "nil")
209
209
  lv = eval("local_variables", bind).collect{|m| m.to_s}
210
210
  iv = eval("instance_variables", bind).collect{|m| m.to_s}
211
211
  cv = eval("self.class.constants", bind).collect{|m| m.to_s}
@@ -237,7 +237,7 @@ module IRB
237
237
  candidates.uniq!
238
238
  end
239
239
  if doc_namespace
240
- "#{rec.name}#{sep}#{candidates.find{ |i| i == message }}"
240
+ "#{rec.class.name}#{sep}#{candidates.find{ |i| i == message }}"
241
241
  else
242
242
  select_message(receiver, message, candidates, sep)
243
243
  end
@@ -121,6 +121,11 @@ module IRB
121
121
  if @echo.nil?
122
122
  @echo = true
123
123
  end
124
+
125
+ @echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT]
126
+ if @echo_on_assignment.nil?
127
+ @echo_on_assignment = false
128
+ end
124
129
  end
125
130
 
126
131
  # The top-level workspace, see WorkSpace#main
@@ -236,6 +241,15 @@ module IRB
236
241
  # puts "omg"
237
242
  # # omg
238
243
  attr_accessor :echo
244
+ # Whether to echo for assignment expressions
245
+ #
246
+ # Uses IRB.conf[:ECHO_ON_ASSIGNMENT] if available, or defaults to +false+.
247
+ #
248
+ # a = "omg"
249
+ # IRB.CurrentContext.echo_on_assignment = true
250
+ # a = "omg"
251
+ # #=> omg
252
+ attr_accessor :echo_on_assignment
239
253
  # Whether verbose messages are displayed or not.
240
254
  #
241
255
  # A copy of the default <code>IRB.conf[:VERBOSE]</code>
@@ -261,6 +275,7 @@ module IRB
261
275
  alias ignore_sigint? ignore_sigint
262
276
  alias ignore_eof? ignore_eof
263
277
  alias echo? echo
278
+ alias echo_on_assignment? echo_on_assignment
264
279
 
265
280
  # Returns whether messages are displayed or not.
266
281
  def verbose?
@@ -75,7 +75,7 @@ module IRB
75
75
  open(history_file) do |f|
76
76
  f.each { |l|
77
77
  l = l.chomp
78
- if history.last&.end_with?("\\")
78
+ if self.class == ReidlineInputMethod and history.last&.end_with?("\\")
79
79
  history.last.delete_suffix!("\\")
80
80
  history.last << "\n" << l
81
81
  else
@@ -101,19 +101,14 @@ module IRB
101
101
  File.chmod(0600, history_file)
102
102
  end
103
103
  rescue Errno::ENOENT
104
+ rescue Errno::EPERM
105
+ return
104
106
  rescue
105
107
  raise
106
108
  end
107
109
 
108
110
  open(history_file, 'w', 0600 ) do |f|
109
- hist = history.to_a.map { |l|
110
- split_lines = l.split("\n")
111
- if split_lines.size == 1
112
- l
113
- else
114
- split_lines.join("\\\n")
115
- end
116
- }
111
+ hist = history.map{ |l| l.split("\n").join("\\\n") }
117
112
  f.puts(hist[-num..-1] || hist)
118
113
  end
119
114
  end
@@ -46,58 +46,80 @@ module IRB # :nodoc:
46
46
  ]
47
47
 
48
48
  @EXTEND_COMMANDS = [
49
- [:irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
50
- [:irb_print_working_workspace, OVERRIDE_ALL],
51
- [:irb_cwws, OVERRIDE_ALL],
52
- [:irb_pwws, OVERRIDE_ALL],
53
- [:cwws, NO_OVERRIDE],
54
- [:pwws, NO_OVERRIDE],
55
- [:irb_current_working_binding, OVERRIDE_ALL],
56
- [:irb_print_working_binding, OVERRIDE_ALL],
57
- [:irb_cwb, OVERRIDE_ALL],
58
- [:irb_pwb, OVERRIDE_ALL],
59
- ],
60
- [:irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
61
- [:irb_chws, OVERRIDE_ALL],
62
- [:irb_cws, OVERRIDE_ALL],
63
- [:chws, NO_OVERRIDE],
64
- [:cws, NO_OVERRIDE],
65
- [:irb_change_binding, OVERRIDE_ALL],
66
- [:irb_cb, OVERRIDE_ALL],
67
- [:cb, NO_OVERRIDE]],
49
+ [
50
+ :irb_current_working_workspace, :CurrentWorkingWorkspace, "irb/cmd/chws",
51
+ [:irb_print_working_workspace, OVERRIDE_ALL],
52
+ [:irb_cwws, OVERRIDE_ALL],
53
+ [:irb_pwws, OVERRIDE_ALL],
54
+ [:cwws, NO_OVERRIDE],
55
+ [:pwws, NO_OVERRIDE],
56
+ [:irb_current_working_binding, OVERRIDE_ALL],
57
+ [:irb_print_working_binding, OVERRIDE_ALL],
58
+ [:irb_cwb, OVERRIDE_ALL],
59
+ [:irb_pwb, OVERRIDE_ALL],
60
+ ],
61
+ [
62
+ :irb_change_workspace, :ChangeWorkspace, "irb/cmd/chws",
63
+ [:irb_chws, OVERRIDE_ALL],
64
+ [:irb_cws, OVERRIDE_ALL],
65
+ [:chws, NO_OVERRIDE],
66
+ [:cws, NO_OVERRIDE],
67
+ [:irb_change_binding, OVERRIDE_ALL],
68
+ [:irb_cb, OVERRIDE_ALL],
69
+ [:cb, NO_OVERRIDE],
70
+ ],
68
71
 
69
- [:irb_workspaces, :Workspaces, "irb/cmd/pushws",
70
- [:workspaces, NO_OVERRIDE],
71
- [:irb_bindings, OVERRIDE_ALL],
72
- [:bindings, NO_OVERRIDE]],
73
- [:irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
74
- [:irb_pushws, OVERRIDE_ALL],
75
- [:pushws, NO_OVERRIDE],
76
- [:irb_push_binding, OVERRIDE_ALL],
77
- [:irb_pushb, OVERRIDE_ALL],
78
- [:pushb, NO_OVERRIDE]],
79
- [:irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
80
- [:irb_popws, OVERRIDE_ALL],
81
- [:popws, NO_OVERRIDE],
82
- [:irb_pop_binding, OVERRIDE_ALL],
83
- [:irb_popb, OVERRIDE_ALL],
84
- [:popb, NO_OVERRIDE]],
72
+ [
73
+ :irb_workspaces, :Workspaces, "irb/cmd/pushws",
74
+ [:workspaces, NO_OVERRIDE],
75
+ [:irb_bindings, OVERRIDE_ALL],
76
+ [:bindings, NO_OVERRIDE],
77
+ ],
78
+ [
79
+ :irb_push_workspace, :PushWorkspace, "irb/cmd/pushws",
80
+ [:irb_pushws, OVERRIDE_ALL],
81
+ [:pushws, NO_OVERRIDE],
82
+ [:irb_push_binding, OVERRIDE_ALL],
83
+ [:irb_pushb, OVERRIDE_ALL],
84
+ [:pushb, NO_OVERRIDE],
85
+ ],
86
+ [
87
+ :irb_pop_workspace, :PopWorkspace, "irb/cmd/pushws",
88
+ [:irb_popws, OVERRIDE_ALL],
89
+ [:popws, NO_OVERRIDE],
90
+ [:irb_pop_binding, OVERRIDE_ALL],
91
+ [:irb_popb, OVERRIDE_ALL],
92
+ [:popb, NO_OVERRIDE],
93
+ ],
85
94
 
86
- [:irb_load, :Load, "irb/cmd/load"],
87
- [:irb_require, :Require, "irb/cmd/load"],
88
- [:irb_source, :Source, "irb/cmd/load",
89
- [:source, NO_OVERRIDE]],
95
+ [
96
+ :irb_load, :Load, "irb/cmd/load"],
97
+ [
98
+ :irb_require, :Require, "irb/cmd/load"],
99
+ [
100
+ :irb_source, :Source, "irb/cmd/load",
101
+ [:source, NO_OVERRIDE],
102
+ ],
90
103
 
91
- [:irb, :IrbCommand, "irb/cmd/subirb"],
92
- [:irb_jobs, :Jobs, "irb/cmd/subirb",
93
- [:jobs, NO_OVERRIDE]],
94
- [:irb_fg, :Foreground, "irb/cmd/subirb",
95
- [:fg, NO_OVERRIDE]],
96
- [:irb_kill, :Kill, "irb/cmd/subirb",
97
- [:kill, OVERRIDE_PRIVATE_ONLY]],
104
+ [
105
+ :irb, :IrbCommand, "irb/cmd/subirb"],
106
+ [
107
+ :irb_jobs, :Jobs, "irb/cmd/subirb",
108
+ [:jobs, NO_OVERRIDE],
109
+ ],
110
+ [
111
+ :irb_fg, :Foreground, "irb/cmd/subirb",
112
+ [:fg, NO_OVERRIDE],
113
+ ],
114
+ [
115
+ :irb_kill, :Kill, "irb/cmd/subirb",
116
+ [:kill, OVERRIDE_PRIVATE_ONLY],
117
+ ],
98
118
 
99
- [:irb_help, :Help, "irb/cmd/help",
100
- [:help, NO_OVERRIDE]],
119
+ [
120
+ :irb_help, :Help, "irb/cmd/help",
121
+ [:help, NO_OVERRIDE],
122
+ ],
101
123
 
102
124
  ]
103
125
 
@@ -51,6 +51,7 @@ module IRB # :nodoc:
51
51
  @CONF[:IGNORE_SIGINT] = true
52
52
  @CONF[:IGNORE_EOF] = false
53
53
  @CONF[:ECHO] = nil
54
+ @CONF[:ECHO_ON_ASSIGNMENT] = nil
54
55
  @CONF[:VERBOSE] = nil
55
56
 
56
57
  @CONF[:EVAL_HISTORY] = nil
@@ -83,7 +84,7 @@ module IRB # :nodoc:
83
84
  :SIMPLE => {
84
85
  :PROMPT_I => ">> ",
85
86
  :PROMPT_N => ">> ",
86
- :PROMPT_S => nil,
87
+ :PROMPT_S => "%l> ",
87
88
  :PROMPT_C => "?> ",
88
89
  :RETURN => "=> %s\n"
89
90
  },
@@ -172,6 +173,10 @@ module IRB # :nodoc:
172
173
  @CONF[:ECHO] = true
173
174
  when "--noecho"
174
175
  @CONF[:ECHO] = false
176
+ when "--echo-on-assignment"
177
+ @CONF[:ECHO_ON_ASSIGNMENT] = true
178
+ when "--noecho-on-assignment"
179
+ @CONF[:ECHO_ON_ASSIGNMENT] = false
175
180
  when "--verbose"
176
181
  @CONF[:VERBOSE] = true
177
182
  when "--noverbose"
@@ -205,7 +205,12 @@ class RubyLex
205
205
 
206
206
  begin # check if parser error are available
207
207
  verbose, $VERBOSE = $VERBOSE, nil
208
- RubyVM::InstructionSequence.compile(code)
208
+ case RUBY_ENGINE
209
+ when 'jruby'
210
+ JRuby.compile_ir(code)
211
+ else
212
+ RubyVM::InstructionSequence.compile(code)
213
+ end
209
214
  rescue SyntaxError => e
210
215
  case e.message
211
216
  when /unterminated (?:string|regexp) meets end of file/
@@ -293,7 +298,16 @@ class RubyLex
293
298
  when :on_kw
294
299
  next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
295
300
  case t[2]
296
- when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
301
+ when 'do'
302
+ if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_CMDARG)
303
+ # method_with_bock do; end
304
+ indent += 1
305
+ else
306
+ # while cond do; end # also "until" or "for"
307
+ # This "do" doesn't increment indent because "while" already
308
+ # incremented.
309
+ end
310
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
297
311
  indent += 1
298
312
  when 'if', 'unless', 'while', 'until'
299
313
  # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
@@ -327,7 +341,16 @@ class RubyLex
327
341
  when :on_kw
328
342
  next if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_FNAME)
329
343
  case t[2]
330
- when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
344
+ when 'do'
345
+ if index > 0 and @tokens[index - 1][3].allbits?(Ripper::EXPR_CMDARG)
346
+ # method_with_bock do; end
347
+ depth_difference += 1
348
+ else
349
+ # while cond do; end # also "until" or "for"
350
+ # This "do" doesn't increment indent because "while" already
351
+ # incremented.
352
+ end
353
+ when 'def', 'case', 'for', 'begin', 'class', 'module'
331
354
  depth_difference += 1
332
355
  when 'if', 'unless', 'while', 'until'
333
356
  # postfix if/unless/while/until/rescue must be Ripper::EXPR_LABEL
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.1.0.pre.2"
14
+ VERSION = "1.1.0.pre.3"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2019-07-15"
16
+ @LAST_UPDATE_DATE = "2019-09-01"
17
17
  end
@@ -9,6 +9,9 @@
9
9
  #
10
10
  #
11
11
  #
12
+
13
+ require "delegate"
14
+
12
15
  module IRB # :nodoc:
13
16
  class WorkSpace
14
17
  # Creates a new workspace.
@@ -49,17 +52,21 @@ EOF
49
52
  @binding = BINDING_QUEUE.pop
50
53
 
51
54
  when 3 # binding in function on TOPLEVEL_BINDING(default)
52
- @binding = eval("self.class.send(:remove_method, :irb_binding) if defined?(irb_binding); def irb_binding; private; binding; end; irb_binding",
55
+ @binding = eval("self.class.send(:remove_method, :irb_binding) if defined?(irb_binding); private; def irb_binding; binding; end; irb_binding",
53
56
  TOPLEVEL_BINDING,
54
57
  __FILE__,
55
58
  __LINE__ - 3)
56
59
  end
57
60
  end
61
+
58
62
  if main.empty?
59
63
  @main = eval("self", @binding)
60
64
  else
61
65
  @main = main[0]
62
- IRB.conf[:__MAIN__] = @main
66
+ end
67
+ IRB.conf[:__MAIN__] = @main
68
+
69
+ unless main.empty?
63
70
  case @main
64
71
  when Module
65
72
  @binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
@@ -71,6 +78,28 @@ EOF
71
78
  end
72
79
  end
73
80
  end
81
+
82
+ case @main
83
+ when Object
84
+ use_delegator = @main.frozen?
85
+ else
86
+ use_delegator = true
87
+ end
88
+
89
+ if use_delegator
90
+ @main = SimpleDelegator.new(@main)
91
+ IRB.conf[:__MAIN__] = @main
92
+ @main.singleton_class.class_eval do
93
+ private
94
+ define_method(:exit) do |*a, &b|
95
+ # Do nothing, will be overridden
96
+ end
97
+ define_method(:binding, Kernel.instance_method(:binding))
98
+ define_method(:local_variables, Kernel.instance_method(:local_variables))
99
+ end
100
+ @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
101
+ end
102
+
74
103
  @binding.local_variable_set(:_, nil)
75
104
  end
76
105
 
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.1.0.pre.2
4
+ version: 1.1.0.pre.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keiju ISHITSUKA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-14 00:00:00.000000000 Z
11
+ date: 2019-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reline
@@ -119,14 +119,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
- version: '0'
122
+ version: '2.4'
123
123
  required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  requirements:
125
125
  - - ">"
126
126
  - !ruby/object:Gem::Version
127
127
  version: 1.3.1
128
128
  requirements: []
129
- rubygems_version: 3.0.4
129
+ rubygems_version: 3.0.3
130
130
  signing_key:
131
131
  specification_version: 4
132
132
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).