Ruby のお勉強 - proc, lambda, method, ブロック -

公開日:2014-12-27

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"
引数がない場合はこのように書ける。