備忘録のようなものなので間違っていたらコメントください
また参考にしたQiita の記事を自分で実行しながら、自分の理解のために記事を書きました。
参考の記事を見たほうがわかりやすいと思います。
https://qiita.com/k-penguin-sato/items/7f98335ef631ea5ce7ad
https://qiita.com/genya0407/items/1a34244cba6c3089a317
Procとは何か
ブロックをまとめてオブジェクトにしたもの
理解をするのにブロックとメソッドのyieldについての理解が必要になる
#ブロックとは何か
do end
もしくは{}で囲まれたもの
ex)引数を受け取りその数字の回数分数字を表示する。
//これのdo から endまで
10.times do |i|
puts i
end
//{}で囲まれている部分
10.times { |i| puts i }
do |parameter|
parameter.times do |i|
puts i
end
end
メソッドとyieldについて
まずメソッドは以下のような形式をとる
そしてyieldは、10を引数としてhogeに対してブロックを用いて実行する。
//メソッド
//引数10のブロックの実行をする。
def hoge
yield(10)
end
//メソッドの実行例
//メソッドを呼び出してyieldで受け取った引数10を使って0~9の数字の表示をしている。
hoge do |parameter|
parameter.times do |i|
puts i
end
end
//実行結果
0
1
2
3
4
5
6
7
8
9
Procについて
Procはブロックをオブジェクトにまとめたもの
Procはdo end, {}のブロックをまとめている。
//ここでは、0から引数まで表示するブロックをproc1にまとめている。
proc1 = Proc.new do |parameter|
parameter.times do |i|
puts i
end
end
//Procの実行方法
//引数として10を渡してプロックの実行をしてる。
proc1.call(10)
//実行結果
0
1
2
3
4
5
6
7
8
9
メソッドの引数をProcオブジェクトにしてそれをメソッドとして実行する方法
Procオブジェクトを引数にして、関数内ではそのprocの呼び出しのproc.callを行う。
メソッドではyieldを用いてブロックを受け取って実行をしていたが、ここではProcを受け取ってProcの実行のためにメソッド内においてproc.call(引数)を行う。
//&procとして、渡されたブロックをProcオブジェクトに変換してメソッドの引数としている。*1
//proc.callによってprocにまとめられたブロックを実行できる。
//proc.call(20)はprocの引数を20としている。
def method2(&proc)
proc.call(10)
end
//メソッドの実行
//ここで、メソッドの引数であるprocの記載をしている。
method2 do |parameter|
parameter.times do |i|
puts i
end
end
//実行結果
0
1
2
3
4
5
6
7
8
9
*1
なぜこのようなことをしているのか
ここでは、引数がブロック引数であるということを明示的に示している。
(推測:プログラムの設計とか分かりやすさからやってるかも?)
そしてここで、ブロックをProcオブジェクトに変換している。
なぜProcオブジェクトに変換する必要があるのかというと、ブロックは変数に代入することが出来ない。
よってProcオブジェクトとしてまとめている。参考資料2からブロックの記載をお借りしました。
//これら二つについてはエラーが出る。
a = { |e| e + 1 }
a = do |e|
e + 1
end
参考資料
https://qiita.com/k-penguin-sato/items/7f98335ef631ea5ce7ad
https://qiita.com/genya0407/items/1a34244cba6c3089a317