🤖

【bugs.ruby Advent Calender】ブロック引数で匿名引数を受け取りたい話【11日目】

2024/12/11に公開

bugs.ruby Advent Calender 11日目の記事です。

これはなに

今年1年間通してみてきた bugs.ruby のチケットの中から気になったものを1つずつ取り上げていく Advent Calender です。
取り上げるチケットは基本的にこのブログで取り上げたものになります。
記事のまとめは ここを参照 してください。

[Feature #19370] Anonymous parameters for blocks?

Ruby 3.2 から以下のように名前のない引数を定義し、それを別のメソッドにフォワードできるようになりました。

def func(*, **)
  p(*, **)
end

func(1, 2, a: 3)
__END__
output:
1
2
{:a=>3}

ただし、このフォワードの仕方はブロックの引数では利用することができません(厳密にいうとブロックの匿名引数を別のメソッドにフォワードすることができない。

body = proc { |*, **|
  # error: no anonymous rest parameter (SyntaxError)
  pp(*)
}

このチケットではブロック内でも匿名引数のフォワードをサポートしてほしいという旨のチケットになります。

だったんですが、チケット内では以下のように『メソッドの匿名引数をブロック内からフォワードした場合に混乱する可能性がある』ということでそちらを禁止する話にシフトしました。

def func(*, **)
  proc { |*, **|
    # ここの匿名引数はブロック引数ではなくて func の方の引数をフォワードする
    pp(*, **)
  }.call(4, 5, b: 6)
end

func(1, 2, a: 3)

上記のような書き方は Ruby 3.3 からシンタックスエラーになるようになったんですが、この対応起因で Ruby 3.3 で意図しないバグが発生することに…。

そういえば書いてから思ったんですがこのチケット自体のことは記事にしてませんでしたね。
Ruby 3.3 のバグの話は下記を参照してください。

関連

GitHubで編集を提案

Discussion