【一人 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
天才か???