📖

[Feature #20508] 無名引数の値を取得する提案

2024/05/25に公開

[Feature #20508] Explicit access to *, **, &, and ...

  • Ruby で特定の引数の値を取得する機能を追加する提案
  • 例えば無名のブロック引数の場合は値を取得できないことがある
def splats(one, *, two: nil, **, &)
  # 以下のように無名の位置引数とキーワード引数は出力できる
  p(*)    # => 1
  p(**)   # => {:three=>3}

  # しかしブロック引数は出力できない
  # これはブロック引数のオブジェクトではなくてブロック引数が p に渡されているため
  p(&)

  p binding.local_variables
  # => [:one, :two, :_]
end

splats(:arg, 1, two: true, three: 3) do
  42
end
  • まあ〜無名引数なんで通常はアクセスするのはむずかしいですねー
  • チケットには以下のように binding 経由でアクセスする提案がされています
def splats(one, *, true: nil, **, &)
  binding.arguments         # 位置引数を返す
  binding.keyword_arguments # キーワード引数を返す
  binding.block_argument    # ブロック引数を返す
end
  • メタプロとかやっているときは普通に便利そう
  • ちなみに以下のようなヘルパ用の proc を書けば意図する情報を取得することができるとコメントにかいてありますね
arguments, keyword_arguments, block_argument = ->(*a, **kw, &b){[a, kw, b]}.(*, **, &);
  • とはいえ利用するときは無名引数だけじゃなくて全部の引数がほしいことが多い気がするから binding のメソッドとして生えていたほうが便利そう
GitHubで編集を提案

Discussion