【Ruby】ブロックをメソッドに渡す
ブロックをメソッドに渡して実行する方法まとめ(備忘録)
【目次】
1.ブロックを渡してyieldで実行
-1.1 引数1つ
-1.2 引数複数
2.ブロックを渡してcallで実行
-2.1 引数1つ
-2.2 引数複数
3.Procをブロックとして渡して実行(yieldでもcallでも可能)
-3.1 引数1つ
-3.2 引数複数
4.Procを普通の引数として渡してcallで実行
-4.1 引数1つ
-4.2 引数複数
5.lambdaをブロックとして渡して実行(yieldでもcallでも可能)
-5.1 引数1つ
-5.2 引数複数
6.lambdaを普通の引数として渡してcallで実行
-6.1 引数1つ
-6.2 引数複数
それではやっていきますーーー
1.ブロックを渡してyieldで実行
-1.1 引数1つ(check_condition メソッドに、条件のブロックを渡す)
def check_conditionif yield Random.rand(50)puts "OK"elseputs "NG"endendcheck_condition do |condition|puts condition100 >= condition * 5end
結果(2回実行)
12
OK
=> nil
44
NG=> nil
-1.2 引数複数
def check_conditionif yield Random.rand(20),Random.rand(20)puts "OK"elseputs "NG"endendcheck_condition do |condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2end
結果(2回実行)
2.ブロックを渡してcallで実行
-2.1 引数1つ
def check_condition(&block)if block.call(Random.rand(50))puts "OK"elseputs "NG"endendcheck_condition do |condition|puts condition100 >= condition * 5end
結果(2回実行)
-2.2 引数複数
def check_condition(&block)if block.call(Random.rand(20),Random.rand(20))puts "OK"elseputs "NG"endendcheck_condition do |condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2end
結果(2回実行)
※callの代わりに、下記のようにyieldでも実行可能
def check_condition(&block)if yield Random.rand(20),Random.rand(20)puts "OK"elseputs "NG"endendcheck_condition do |condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2end
3.Procをブロックとして渡して実行(yieldでもcallでも可能)
-3.1 引数1つ
def check_conditionif yield Random.rand(50)puts "OK"elseputs "NG"endendcondition = Proc.new{|condition1|puts condition1100 >= condition1 * 5}# block として渡すので、&conditionとするcheck_condition(&condition)
結果(二回実行)
block として渡すので、下記のようにcallでも実行可能
def check_condition(&block)if block.call(Random.rand(50))puts "OK"elseputs "NG"endendcondition = Proc.new{|condition1|puts condition1100 >= condition1 * 5}# block として渡すので、&conditionとするcheck_condition(&condition)
-3.2 引数複数
def check_conditionif yield Random.rand(20),Random.rand(20)puts "OK"elseputs "NG"endendcondition = Proc.new{|condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2}check_condition(&condition)
結果(二回実行)
block として渡すので、下記のようにcallでも実行可能
def check_condition(&block)if block.call(Random.rand(20),Random.rand(20))puts "OK"elseputs "NG"endend
condition = Proc.new{|condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2}
check_condition(&condition)
4.Procを普通の引数として渡してcallで実行
-4.1 引数1つ
def check_condition(proc1)if proc1.call(Random.rand(30))puts "OK"elseputs "NG"endendcondition = Proc.new{|condition1|puts condition1100 >= condition1 * 5}# blockではなく普通の変数として渡すので、&はいらないcheck_condition(condition)
結果(二回実行)
※block ではなく、普通の引数として渡すので、yieldを使用してしまうとエラーになる
def check_condition(proc1)# callではなくyieldを使うif yield Random.rand(30)puts "OK"elseputs "NG"endendcondition = Proc.new{|condition1|puts condition1100 >= condition1 * 5}check_condition(condition)
結果
no block given (yield)
(repl):2:in `check_condition'
(repl):11:in `<main>'
-4.2 引数複数
def check_condition(proc1)
if proc1.call(Random.rand(20),Random.rand(20))
puts "OK"
else
puts "NG"
end
end
condition = Proc.new{|condition1, condition2|
puts condition1
puts condition2
100 >= condition1 * condition2}
check_condition(condition)
結果(二回実行)
※応用:メソッドにprocを複数渡せる
def check_condition(proc1,proc2)if proc1.call(Random.rand(50)) && proc2.call(Random.rand(20),Random.rand(20))puts "OK"elseputs "NG"endendcond1 = Proc.new{|condition|puts condition100 >= condition * 5}cond2 = Proc.new{|condition1, condition2|puts condition1puts condition2100 >= condition1 * condition2}check_condition(cond1,cond2)
(最初のproc1でfalseになったため、proc2.callが実行されない)
5.lambdaをブロックとして渡して実行(yieldでもcallでも可能)
-5.1 引数1つ
def check_conditionif yield Random.rand(50)puts "OK"elseputs "NG"endend# lambda生成condition = ->condition1{puts condition1100 >= condition1 * 5}check_condition(&condition)
結果(二回実行)
-5.2 引数複数
6.lambdaを普通の引数として渡してcallで実行
-6.1 引数1つ
def check_condition(lambda1)if lambda1.call(Random.rand(30))puts "OK"elseputs "NG"endendcondition = -> condition1{puts condition1100 >= condition1 * 5}check_condition(condition)
結果(二回実行)
-6.2 引数複数
def check_condition(lambda1)if lambda1.call(Random.rand(20),Random.rand(20))puts "OK"elseputs "NG"endendcondition = -> condition1, condition2{puts condition1puts condition2100 >= condition1 * condition2}check_condition(condition)
結果(二回実行)
※応用:メソッドにlambdaを複数渡せる
def check_condition(lambda1,lambda2)if lambda1.call(Random.rand(50)) && lambda2.call(Random.rand(20),Random.rand(20))puts "OK"elseputs "NG"endendcond1 = -> condition{puts condition100 >= condition * 5}cond2 = -> condition1, condition2{puts condition1puts condition2100 >= condition1 * condition2}check_condition(cond1,cond2)
(最初のlambda1でfalseになったので、lambda2が実行されない)
以上ですーーー!!
ブロックを渡すことで、メソッドの数を少なくできる(条件ごとにメソッドを作らなくていいなど。)ことがわかりました!
他にも色々と応用できそうです^^
yeildとcallの違いや、procとlambdaの違いなどは、今後まとめられればいいなと思いますーーー!
おやすみなさいいいぃぃぃ