🙌
[Feature #21813] ...引数のメタ情報を Method#parameters で取得できるようにする提案
[Feature #21813] Add [:forward, :...] symbol tuple to indicate forwarding arguments when calling Method#parameters
-
***&引数の場合にMethod#parametersで引数のシグネチャを取得しようとすると以下のように***&の情報をそのまま取得できる
def foo(*, **, &)
end
pp method(:foo).parameters
# => [[:rest, :*], [:keyrest, :**], [:block, :&]]
- なのでこの情報を利用して以下のように動的にメソッドの引数を参照する事ができる
def foo(*, **, &)
method(__method__).parameters => [*, [:rest, rest], *]
p rest # => :*
# print(*) と同等
binding.eval "print(#{rest})" # => 123
end
foo(1, 2, 3)
- 一方で
...引数の場合は...ではなくて***&の情報が返ってくる
def foo(...)
end
pp method(:foo).parameters
# => [[:rest, :*], [:keyrest, :**], [:block, :&]]
- なので先程書いたような動的にメソッドの引数を参照するとエラーになってしまう
def foo(...)
# `...` という記号で受け取る事ができない
method(__method__).parameters => [*, [:rest, rest], *]
p rest # => :*
# print(*) と呼び出そうとするが引数のシグネチャが異なるのでエラーになる
binding.eval "print(#{rest})" # => 123
# error: unexpected `*`; no anonymous rest parameter
end
foo(1, 2, 3)
- これに対応するために
...引数の場合はMethod#parametersの戻り値を[:forward, :...]にする提案 - メタプロする場合はこういうのがボトルネックになるので普通にほしいなあ
Discussion