💭
[Feature #20211] Ruby 3.4 でブロックの引数の匿名引数をフォワードできるようにする提案
[Feature #20211] Consider re-adding 3.2-style support of Anonymous Args/Blocks
- Ruby 3.3 では次のように匿名引数のフォワードが禁止された
def m(*)
[1, 2, 3].each { |*| p(*) }
end
m('test', 'test', 'test')
# Ruby 3.2 => p('test', 'test', 'test') が呼ばれる
# Ruby 3.3 => error: anonymous rest parameter is also used within block (SyntaxError)
- これに伴い Rubocop が autofix することによって Ruby 3.1+ のコードを上記の問題になるコードに変換してしまう問題があるらしい
- Class: RuboCop::Cop::Naming::BlockForwarding — Documentation for rubocop (1.62.1)
- Class: RuboCop::Cop::Style::ArgumentsForwarding — Documentation for rubocop (1.62.1)
-
[1, 2, 3].each { |*a| p(*a) }
を[1, 2, 3].each { |*| p(*) }
にしてしまうのかな?
- その上で以下のような挙動にする案も提示されていますね
def m(*)
[1, 2, 3].each { p(*) }
end
m('test', 'test', 'test')
# Ruby 3.2 => p('test', 'test', 'test') が呼ばれる
# Ruby 3.3 => p('test', 'test', 'test') が呼ばれる
# Ruby 3.4 => p('test', 'test', 'test') が呼ばれる
def m(*)
# このときにブロック引数の * を優先する
[1, 2, 3].each { |*| p(*) }
end
m('test', 'test', 'test')
# Ruby 3.2 => p('test', 'test', 'test') が呼ばれる
# Ruby 3.3 => error: anonymous rest parameter is also used within block (SyntaxError)
# Ruby 3.4 => p(1) p(2) p(3) が呼ばれる
- 個人的にはこっちの方が期待する挙動としては自然な気がしますねー
Discussion