iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0

物件

介紹 Proc 跟 Lambda 前先來介紹一下 Ruby 的物件。
在 Ruby 裡幾乎所有東西都是物件,只有 block、method 以及 if else 不是物件。

block

  • 沒辦法單獨存活,但可寄生在別的方法後面
  • 是一段不會被主動執行的程式碼
  • 會自動回傳最後一行的執行結果

block 有兩種型態:

  1. do end
    結合率較弱,有多行通常會用 do end
  2. {}
    結合率較強,只有一行通常會用{}

yield

用來執行 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 vs Lambda

相同點:

其中 Proc 跟 Lambda 都是可以讓 block 物件化的方法,讓 block 能單獨存在,變成可被呼叫的物件。
加入 Proc 或 Lambda 後就可以用 call 來呼叫他了。

範例:

a = Proc.new {|n| n * 2 }
a = -> (n) { n + 2 }
p a.call(2)

範例第一行是使用 Proc 的寫法,
第二行是使用 Lambda 的寫法,
兩者都會印出 4,可以擇一使用。

兩個差異點:

  1. Lambda 會檢查代入的引數(Argument)數量,但 Proc 不會。
    當使用 Lambda 且引數數量有錯時,錯誤訊息會跟你說,使用 Proc 時則不會告訴你。

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)

  1. 如果在 Proc 的 block 內加入 return 會立即跳出,不會執行裡面的程式碼,而在 Lambda 的 block 內加入 return 會轉移控制權給 block,繼續執行裡面的程式碼。

範例:

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?


上一篇
Day 18 Rails MVC
下一篇
Day 20 Ruby 封裝 vs 繼承
系列文
網頁前後端寶石庫-礦坑補完計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言