“yield” 在 ruby 裡代表什麼?又做了什麼事?
Yield 是一個關鍵字,可以在方法裡面使用去呼叫一個 block,呼叫後會執行 block 裡的程式碼(就像是呼叫一個方法),Yield 可以傳任何的參數給 block ,而 block 的回傳值就會是 yield 的回傳值。
可以想像成 block 就是一個沒有名稱的方法,可以傳額外的參數給其他的方法。
def make_salad
yield "lettuce"
yield "carrots"
yield "olive oil"
end
make_salad { |ingredient| puts "Adding #{ingredient} to salad!" }
這裡呼叫了 block 三次
Adding lettuce to salad!
Adding carrots to salad!
Adding olive oil to salad!
看起來就像是呼叫一個方法,但其事實呼叫一個 block。
現在來看看,如果沒有 block 可以呼叫的狀況,如果你呼叫 yield 卻沒有 block,那就會得到一個錯誤訊息。
def write_code
yield
end
write_code
# LocalJumpError: no block given (yield)
這裡的錯誤很明顯,沒有給 block 。那如何預防這個錯誤?
def write_code
yield if block_given?
end
使用 The block_given? 方法去檢查是否有 block 當有的時候才會執行。
使用 yield 來執行 blocks.
使用 block 來傳一些程式碼,就像傳程式碼給方法一樣。在某些狀況下是有用的。當要寫一個 logging function , logs 需要花一些時間跑,想要在方法跑完的時候執行一個程式碼(像是 JS 裡面的 “callbacks”),想要 “lazy code”,程式碼只會在需要的時候執行而自己可以客製化。
或許已經發現了新的 yield_self 方法,看起來好像跟 yield 有什麼關係,其實並沒有。因為 self 會參照到當前的物件。在任何想要使用的地方把方法串起來,對使用 yield_self 方法呼叫的物件做一些事情。
n_squared = ->(n) { n ** 2 }
2
.yield_self(&n_squared)
.yield_self(&n_squared)
# 16
不要跟一般的 yield 搞混了。