ブロックをパラメーターとして受け取るメソッドを設定しようとしています。最後のパラメーターに & プレフィックスを付けることでこれを行うことは知っていますが、渡されたら、どのように確認すればよいですか?
引数が文字列であることを確認したい場合は、is_a?(String)
たとえば を使用できます。しかし、1 つのパラメーターを受け入れるブロックを受け取ったことを確認するにはどうすればよいでしょうか? それとも2?
ブロックをパラメーターとして受け取るメソッドを設定しようとしています。最後のパラメーターに & プレフィックスを付けることでこれを行うことは知っていますが、渡されたら、どのように確認すればよいですか?
引数が文字列であることを確認したい場合は、is_a?(String)
たとえば を使用できます。しかし、1 つのパラメーターを受け入れるブロックを受け取ったことを確認するにはどうすればよいでしょうか? それとも2?
メソッドを使用してProc#arity
、ブロックが受け入れる引数の数を確認できます。
def foo(&block)
puts block.arity
end
foo { } # => 0
foo { |a| } # => 1
foo { |a, b| } # => 2
ドキュメントから:
無視されない引数の数を返します。ブロックが引数を取らないと宣言されている場合は、0 を返します。ブロックが正確に n 個の引数を取ることがわかっている場合は、n を返します。ブロックにオプションの引数がある場合は、-n-1 を返します。ここで、n は必須の引数の数です。引数宣言のない proc は、|| を宣言するブロックと同じです。その引数として。
ブロックはオブジェクトではないので、ブロックを使って何か役に立つことはできません (yield
もちろんブロックを除いて)。
つまり、それらを参照する方法はなく、名前にもバインドされていません。
def foo
yield 'foo'
end
foo do |bar| puts bar end
# foo
内部foo
では、ブロックは変数にバインドされておらず、参照することもできないため、明らかにそのパラメーターについてもクエリできません。
ただし、Ruby にブロックを に変換してパラメーターにバインドするように依頼することはできます。Proc
その後、名前で参照でき、以下を含む完全なProc
API を自由に使用できますProc#parameters
。
def foo(&blk)
blk.parameters
end
foo do |m1, m2, o1=:o1, o2=:o2, *splat, m3, m4,
ok1: :ok1, mk1:, mk2:, ok2: :ok2, **ksplat, &blk| end
# => [[:opt, :m1],
# [:opt, :m2],
# [:opt, :o1],
# [:opt, :o2],
# [:rest, :splat],
# [:opt, :m3],
# [:opt, :m4],
# [:keyreq, :mk1],
# [:keyreq, :mk2],
# [:key, :ok1],
# [:key, :ok2],
# [:keyrest, :ksplat],
# [:block, :blk]]
ただし、「ブロックのアリティ」という概念は、Ruby では複雑な概念であることに注意してください。これは、ブロックのパラメーター バインディング セマンティクスが緩いためです。ブロックのパラメータ バインディング セマンティクスは、特にアリティに関しては、メソッドのパラメータ バインディング セマンティクスとは異なります。
Array
パラメーターへの単一のバインドとして渡されます (パラメーターがパラメーターとして宣言されているかのように*splat
)。Array
代わりにその個々の要素が引数として渡されます (引数として渡されたかのように*splat
)。nil
ます。全体として、セマンティクスはメソッド呼び出しよりも割り当てのセマンティクスに近いです。
たとえば、 と はブロック内で必須の位置パラメータとして宣言されていますが、それらの型は 、つまりオプションのパラメータとしてリストされていることに注意m1
しm2
てProc#parameters
ください:opt
。
つまり、1 つのパラメーターのみを宣言するブロックでも 2 つの引数を取り、2 つのパラメーターを宣言するブロックは 1 つの引数だけで呼び出すことができます。
これが役立つ 1 つの例: ミックスイン全体が、単一の要素であるEnumerable
メソッドに基づいています。ただし、 の場合、実際には2 つの引数を処理する必要があります。sは2 つの要素であり、2 つのパラメーターを宣言するが 1 つの引数のみを受け取るブロックは、そのパラメーター全体でその引数を「スプラット」するため、キーがバインドされ、値がバインドされずにバインドされるため、できます。すべてのs メソッドの 2 引数バージョンをコピーして貼り付けます。yield
Hash
key, value
Hash#each
yield
Array
key
value
Enumerable