はじめに
def block_execute(&block) # ← ここの引数の「&」の意味がわからない
puts "block.call"
end
block_execute do
puts "blockを実行"
end
def block_execute(&block)
これを見て、(&block)ってどんな引数だよ!!
と思ったので調べました。
結論
(&block)の「&」がついた引数は、ブロック引数と呼ばれるものです。
解説
ブロック引数の前にブロックとは何か?
ブロックとは?
メソッド実行時に、そのメソッドの引数として渡せる「処理のかたまり」のこと。
今回で言うとここ↓
block_execute do
puts "blockを実行"
end
または、
block_execute { puts "blockを実行" }
ブロックは
- do ~ end で囲まれた処理のかたまり
- {} で書くことも可能
- メソッドに渡すためだけに存在する
ブロック引数とは?
ブロックを受け取る専用の引数のこと。
正確に言うと、「&」をつけると「 ブロックをProcオブジェクトとして受け取れるようになる 」です。
※ブロック自体はオブジェクトではない(データではない)のでそのままだと受け取ることができないということです。
Procオブジェクトについてはわからない人は調べてみてください。
参考: https://qiita.com/nagata03/items/919b0457409cc755ff0f
通常の引数は以下のように指定します。
def method(arg)
end
しかし、ブロック引数は以下のように指定します。
def method(&arg) # 「&」 が付きます
end
以上のように引数に「&」を付け足してあげることで、ブロック(処理のかたまり)を受け取ることができるようになります。
動作確認
ブロックを渡して、正しくブロックが実行されるかを見てみましょう。
def block_execute(&block)
block.call
end
block_execute do
puts "blockを実行しました"
end
=> blockを実行しました
成功です。
次に、引数の「&」を消してみましょう。すると、、、
def block_execute(block) # ← 「&」を消してみた
block.call
end
block_execute do
puts "blockを実行しました"
end
=> wrong number of arguments (given 0, expected 1) (ArgumentError)
うまく渡せませんでした。
ちなみに、今回使用しているブロックは「ブロック付きメソッド」と呼ばれるメソッドになります。
# ブロック付きメソッド
block_execute do
puts "blockを実行しました"
end
ブロック付きメソッドがどのようにして呼び出されているかは、以下の記事が参考になります。
https://qiita.com/shuhei_sfc/items/5c582f89d5d8d7ab956c
まとめ
def block_execute(&block) このように引数に「&」が付くとブロックをProcオブジェクトとして受け取れるようになるとということでした。