【一人 bugs.ruby Advent Calendar 2021】[Feature #17785] Allow named parameters to be keywords【5日目】

一人 bugs.ruby Advent Calendar 2021 5日目の記事になります。
今回はキーワード引数にキーワードを割り当てたい話。

[Feature #17785] Allow named parameters to be keywords

次のようにキーワード引数に『言語のキーワード』を指定すると参照するのが難しい。

def check(arg, class:)
  # ここで class 引数を使いたいが class はキーワードなので参照できない
  arg.is_a?(class)
end

check(42, class: Integer) # => true

これを キーワード_ という名前で変数参照できるようにしよう、という提案になります。

def check(arg, class:)
  # _ を付けて参照できるようにする
  arg.is_a?(class_)
end

check(42, class: Integer) # => true

一応 local_variable_get で取得する事は可能ではあるんですがちょっとつらそう(あと local_variable_get を使うとパフォーマンス的な懸念点もありそう。
参照:https://bugs.ruby-lang.org/issues/17785#note-1

def check(arg, class:)
  # local_variable_get で動的に変数を取得する
  class_ = binding.local_variable_get(:class)
  arg.is_a?(binding.local_variable_get(:class))
end

check(42, class: Integer) # => true

foo(class_, class:) みたいな場合だと不都合じゃない?などコメントされていますね。
\class みたいな書き方も提案されていて混沌としてる…。

def check(arg, class:)
  arg.is_a?(\class)
end

# キーワード引数以外も適用可能
def diff(start, \end)
  \end - start
end

他には __params__ みたいな値で受け取れるようにしようという提案があってこれは普通にほしいと思った

def check(arg, class:)
  arg.is_a?(__params__[:class])
end

check(42, class: Integer) # => true

ただし、キーワード引数以外の引数をどうするかの課題があるみたい。
__params__ というよりかは __keyword_params__ みたいな名前になるんですかね。
ちなみに Ruby 3.1 では次のようにして Hash を経由してキーワードの変数を参照できます。

def check(arg, class:)
  # Ruby 3.1 の Hash のショートハンドで取得する
  class_ = {class:}[:class]
  arg.is_a?({class:}[:class])
end

check(42, class: Integer) # => true

天才か???