介紹 Proc 跟 Lambda 前先來介紹一下 Ruby 的物件。
在 Ruby 裡幾乎所有東西都是物件,只有 block、method 以及 if else 不是物件。
block 有兩種型態:
用來執行 block 內的程式碼。
範例:
def say_hello
puts "Hello, 你好"
yield
puts "Hello, ⼤家好"
end
say_hello {
puts "here!"
}
puts "there!"
以上範例將 {} 寄生在 say_hello 方法後面,並搭配 yeild 執行 block 內的程式碼,會先後印出:
Hello, 你好 (跳過前4行,執行 say_hello 方法)
here! (yield 轉移控制權到下面的 block)
Hello, ⼤家好 (yield 轉移控制權回到上面的 block)
there! (跳出 say_hello 方法,執行外層的 puts "there!")
其中 Proc 跟 Lambda 都是可以讓 block 物件化的方法,讓 block 能單獨存在,變成可被呼叫的物件。
加入 Proc 或 Lambda 後就可以用 call 來呼叫他了。
範例:
a = Proc.new {|n| n * 2 }
a = -> (n) { n + 2 }
p a.call(2)
範例第一行是使用 Proc 的寫法,
第二行是使用 Lambda 的寫法,
兩者都會印出 4,可以擇一使用。
Proc 範例1:
a = Proc.new {|n| n * 2 }
p a.call()
如果引數個數小於參數會印出 NoMethodError
Proc 範例2:
a = Proc.new {|n| n * 2 }
p a.call(2,3)
如果引數個數大於參數會正常印出 4
Lambda 範例1:
a = -> (n) { n + 2 }
p a.call()
如果引數個數小於參數會印出 wrong number of arguments (given 0, expected 1) (ArgumentError)
Lambda 範例2:
a = -> (n) { n + 2 }
p a.call(2,3)
如果引數個數大於參數會印出 wrong number of arguments (given 2, expected 1) (ArgumentError)
範例:
a = Proc.new { return 2 }
p a.call()
當 Proc 遇到 return 時會跳出,不會執行 block 內的程式。
a = lambda { return 2 }
p a.call()
當 lambda 遇到 return 時不會跳出,可以印出 2。
參考:
[1]What's the difference between a proc and a lambda in Ruby?