再看 tap()
tap()
之前有提過,是 helpers.php 的方法之一。
function tap($value, $callback = null) |
先不管 HigherOrderTapProxy,來看剩下的原始碼:
function tap($value, $callback) |
它需要傳入一個 $value,然後它會再回傳出來,因此可以知道下面這個寫法是可行的:
tap(new Collection(), $callback)->each->pay(); |
再來因為它中間有做 $callback($value)
,因此上面這個方法的全貌可能會是長這樣的:
$callback = function($collection) { |
反過來看,如果沒有 tap() 函式的話,我們可能需要這樣寫:
$collection = new Collection(); |
咦,看起來似乎不用 tap() 寫起來比較乾淨。不是這樣的,是 Collection 並不適合用在這個地方。
最常看到的就是在物件初始化的時候,比方說分析 Session 提到了下面這段程式碼:
protected function startSession(Request $request) |
使用 tap()
的好處之一是剛剛有提到的,這對要使用串聯方法是有利的;另一個好處則是:有時候我們會希望對某個實例做某些事,而做這些事會需要產生一些專用的暫時變數,這時 tap() 因為可以使用 Closure,所以可以把這些暫存變數「關」在裡面,外面就不會被這些暫時變數干擾到。
HigherOrderTapProxy
雖然是這樣,但每次要寫一堆 callable 就很煩,因此出現了另一個選擇:HigherOrderTapProxy,來看看它的原始碼:
// 前面只是建構的時候把 value 存到 target 而已,所以省略 |
這很像 proxy pattern,唯一不同的地方在於,它固定會回傳 self。以 分析 Log 的例子來說,原本程式碼與改寫後的程式碼如下:
tap($this->createEmergencyLogger(), function ($logger) use ($e) { |
跟 Higher Order Messages 很像,可以省略掉一層 callback,但同時也有一樣的使用條件:以 callback 的寫法,只允許一行程式碼。