Ruby のお勉強 - proc, lambda, method, ブロック -
公開日:2014-12-27 更新日:2019-05-13
[Ruby]
proc, lambda, method, ブロック
inc = Proc.new {|_| _ + 1}
a = 0
a = inc.call(a)
p a
1
関数(ブロック)をProcのコンストラクタの引数として渡す。関数は、Proc の call() で呼び出せる。
class Test
#コンストラクタ
def initialize(&block)
p block.call(0)
p block.class
end
end
Test.new {|_| _ + 1}
1
Proc
ブロックは、「&変数名」で受け取れる。使う時は、& をはずす。
def calc(a, b, &block)
block.call(a, b)
end
p calc(1, 2){|p1, p2| p1 + p2}
3
ブロックを関数に渡す時は、() の外で指定する。関数では、最後の引数としてブロックを受け取れる。
def calc(a, b)
#p yield.class #エラーになる
yield(a, b)
end
p calc(1, 2){|p1, p2| p1 + p2}
3
引数でブロックを受け取らなくても、yield で、渡されたブロックを参照できる。
yield.class を実行するとエラーになることから、yield はオブジェクトではないことがわかる。
def test
p proc.class
proc.call(1)
end
p test {|_| _ + 1}
Proc
2
引数でブロックを受け取らなくても、proc で、渡されたブロックを参照できる。
但し、proc はオブジェクトのため、
実行する時は yield と異なり、call() を使う必要がある。
add = Proc.new {|p1, p2| p1 + p2}
p add.call(1, 2)
p add.(1, 2)
p add[1, 2]
#p add(1, 2) #エラーになる
3
3
3
いろんな呼び出し方ができる。わかりづらいので、面倒でも call() を使った方がいいと思う。
add(1, 2) って書けるといいんだけど。
add = lambda{|p1, p2| p1 + p2 }
p add.call(1, 2)
p add.class
3
Proc
Proc.new を lambda で書き換えることもできる。lambda の結果は、Proc.new と同様に Proc なので、実行方法は同じ。
add = ->(p1, p2){p1+p2}
p add.call(1, 2)
p add.class
3
Proc
lambda を -> で書き換えることができる。lambda の時と微妙に書き方が違うので要注意。
def add(p1, p2)
p1 + p2
end
add = method(:add) # method("add") でも動く
p add.call(1, 2)
p add.(1, 2)
p add[1, 2]
p add.class
3
3
3
Method
オブジェクトは Method だが、Proc と同様に関数を実行することができる。lambda {p "test"}.call
->{p "test"}.call
"test"
"test"
引数がない場合はこのように書ける。