LoginSignup
0
0

More than 1 year has passed since last update.

【Ruby】キーワード引数をハッシュ変数として受け取る

Last updated at Posted at 2021-06-20

やりたいこと

このようなメソッドがあるとする。

def my_method(key1:, key2:)
  # do something
end

このメソッドの中で {key1: 引数値, key2: 引数値} のような hash が欲しい。

まずはメソッドの引数の定義情報を得る

定義したメソッドの引数名の一覧は Method#parameters で得られる。

def my_method(key1:, key2:, key3:)
  p method(__method__).parameters
  # => [[:keyreq, :key1], [:keyreq, :key2], [:keyreq, :key3]]
end

my_method(key1: "val1", key2: "val2", key3: "val3")

上記の様に Method#parameters は引数の数だけの要素数の配列を返す。各要素の1つ目の要素は 引数の種類を表すシンボル、2つ目の要素は 引数名 となる。実際の引数の値は含まれない点に留意する。

今回はキーワード引数のデフォルト値を定義してない為、各1つ目の要素は「必須のキーワード引数」を表す :keyreq となっている。

キーワード引数を表すシンボルは :keyreq:key なので、これらに一致する変数をハッシュに変換できれば実現できそう。

ということで実現方法は以下。

キーワード引数をハッシュとして受け取る方法

eval で変数名を評価した結果(つまり変数の値)をハッシュに入れていく。

def my_method(key1:, key2:)
  named_params = method(__method__).parameters.each_with_object({}) do |p, h|
    parameter_type, name = p
    is_keyword_parameter = [:key, :keyreq].include? parameter_type
    next unless is_keyword_parameter

    h[name] = eval(name.to_s)
  end

  p named_params
  # => {:key1=>"val1", :key2=>"val2"}
end

my_method(key1: "val1", key2: "val2")

短縮版

def my_method(key1:, key2:)
  named_params = method(__method__).parameters.each_with_object({}) do |p, h|
    h[p[1]] = eval(p[1].to_s) if [:key, :keyreq].include? p[0]
  end

  p named_params
  # => {:key1=>"val1", :key2=>"val2"}
end

my_method(key1: "val1", key2: "val2")

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0