Bug #17015
Updated by nobu (Nobuyoshi Nakada) over 4 years ago
## Summary `RubyVM::AbstractSyntaxTree.parse("proc { |a| }")` and `RubyVM::AbstractSyntaxTree.parse("proc { |a,| }")` have the same result. Since `proc { |a| }` and `proc { |a,| }` have different meanings, I think we need a way to distinguish them. ```ruby node1 = RubyVM::AbstractSyntaxTree.parse("proc { |a| }") body1 = node1.children.last pp body1 # => (ITER@1:0-1:12 (FCALL@1:0-1:4 :proc nil) # (SCOPE@1:5-1:12 # tbl: [:a] # args: # (ARGS@1:8-1:9 # pre_num: 1 # pre_init: nil # opt: nil # first_post: nil # post_num: 0 # post_init: nil # rest: nil # kw: nil # kwrest: nil # block: nil) # body: (BEGIN@1:10-1:10 nil))) # returns the same result as proc { |a| } node2 = RubyVM::AbstractSyntaxTree.parse("proc { |a,| }") body2 = node2.children.last pp body2 # => (ITER@1:0-1:13 (FCALL@1:0-1:4 :proc nil) # (SCOPE@1:5-1:13 # tbl: [:a] # args: # (ARGS@1:8-1:10 # pre_num: 1 # pre_init: nil # opt: nil # first_post: nil # post_num: 0 # post_init: nil # rest: nil # kw: nil # kwrest: nil # block: nil) # body: (BEGIN@1:11-1:11 nil))) ``` ## Proposal In case of `proc { |a,| }`, `rest: :NODE_SPECIAL_EXCESSIVE_COMMA` is added. ```ruby # no change node1 = RubyVM::AbstractSyntaxTree.parse("proc { |a| }") body1 = node1.children.last pp body1 # => (ITER@1:0-1:12 (FCALL@1:0-1:4 :proc nil) # (SCOPE@1:5-1:12 # tbl: [:a] # args: # (ARGS@1:8-1:9 # pre_num: 1 # pre_init: nil # opt: nil # first_post: nil # post_num: 0 # post_init: nil # rest: nil # kw: nil # kwrest: nil # block: nil) # body: (BEGIN@1:10-1:10 nil))) # rest: :NODE_SPECIAL_EXCESSIVE_COMMA is added node2 = RubyVM::AbstractSyntaxTree.parse("proc { |a,| }") body2 = node2.children.last pp body2 # => (ITER@1:0-1:13 (FCALL@1:0-1:4 :proc nil) # (SCOPE@1:5-1:13 # tbl: [:a] # args: # (ARGS@1:8-1:10 # pre_num: 1 # pre_init: nil # opt: nil # first_post: nil # post_num: 0 # post_init: nil # rest: :NODE_SPECIAL_EXCESSIVE_COMMA # kw: nil # kwrest: nil # block: nil) # body: (BEGIN@1:11-1:11 nil))) ``` This correspondence is similar to `:NODE_SPECIAL_NO_NAME_REST` for `MASGN`. ```ruby node = RubyVM::AbstractSyntaxTree.parse("*a = foo") body = node.children.last pp body # => (MASGN@1:0-1:8 (VCALL@1:5-1:8 :foo) nil (LASGN@1:1-1:2 :a nil)) # :NODE_SPECIAL_NO_NAME_REST is added if the variable name is not defined node = RubyVM::AbstractSyntaxTree.parse("* = foo") body = node.children.last pp body # => (MASGN@1:0-1:7 (VCALL@1:4-1:7 :foo) nil :NODE_SPECIAL_NO_NAME_REST) ``` ## NOTE `NODE_SPECIAL_EXCESSIVE_COMMA` was implemented in [0872ea5](https://github.com/ruby/ruby/commit/0872ea53303499caf3584e40f2a5438e86eb4fed) and renamed in [f258137](https://github.com/ruby/ruby/commit/f258137083051a7fc2412c62e3fb239f93d1fdf8). で実装され、[f258137](https://github.com/ruby/ruby/commit/f258137083051a7fc2412c62e3fb239f93d1fdf8). So backport to 2.6 can be difficult. ## Versions * `ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]` * `ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]` * `ruby 2.8.0dev (2020-07-05T16:15:47Z master efe851a0df) [x86_64-linux]` ## Patch * PR:https://github.com/ruby/ruby/pull/3298