🗂

[Bug #20570] Ruby 3.3 から特定の条件で **nil の引数が壊れているバグ報告

2024/06/13に公開

[Bug #20570] Nokey behavior changed since 3.3.

  • 以下のようなコードで Ruby 3.3 から挙動が変わっているというバグ報告
receiver_value = Set.new
method_name = :merge
args = [1]
kwargs = {}
block = nil

receiver_value.__send__(method_name, *args, **kwargs, &block)
# Ruby 3.2 => `do_with_enum': value must be enumerable (ArgumentError)
# Ruby 3.3 => no keywords accepted (ArgumentError)
def foo(*, **nil); :ok; end

foo(1, **{})    #=> Ruby 3.2: :ok
                #=> Ruby 3.3: :ok
foo(*[1], **{}) #=> Ruby 3.2: :ok
                #=> Ruby 3.3: no keywords accepted (ArgumentError)
  • そもそも no keywords accepted がどういうエラーなのかっていうとメソッドのシグネチャが **nil になっている場合には『キーワード引数を渡せない』定義になるのでそのメソッドに対してキーワード引数を渡そうとするエラーですね
def foo(**nil); :ok; end

# error: no keywords accepted (ArgumentError)
foo(key: 1)
  • またこのときに **{} を渡した場合はエラーにはなりません
def foo(**nil); :ok; end

# no error
foo(**{})
GitHubで編集を提案

Discussion