Block and Proc
Ruby 可以將程式碼參數化,Ruby 稱被參數化的程式碼為 block 。Ruby 語法以 {||}
表示一個 block ,其中的 ||
為參數列宣告,若無參數則可省略。
Ruby 的 Proc
類似 ECMAScript 的 Function
。在 ECMAScript 中使用關鍵字 function
即可配置一個 Function
實例。 Ruby 則使用 Kernel::proc、Kernel::lambda 方法 (兩者相同) 或是直接建構一個 Proc
實例(Proc.new
),需提供一個 block 作為引數。
Ruby: proc { |arguments| codes } ECMAScript: function(arguments) { codes }
Block and Proc
Block 無法單獨存在,只能作為 Ruby 指令或呼叫方法時的引數。Ruby 會主動將 block 參數化,程序員僅需利用流程指令 yield
即可將流程轉移到被參數化的 block 中運行。
Block way. 這種用法較常見。
Proc
way. 細節後述。
用例:
不論是用 block 或是 Proc ,都可以用 Kernel::block_given? 方法判斷使用方有無傳遞 block 。
Proc::call 方法也可以運算子 [ ]
形式調用。上例之 p.call n
亦可寫成 p[n]
。
ECMAScript 只有 Function
類,沒有 block 與 proc 的區分。上述的 Ruby 程式,以 ECMAScript 表達如下列所示:
Block and Method
定義方法時,若參數名稱前冠上 &
符號, Ruby 將自動轉換 block 為 Proc 實例(隱性調用 Proc.new),令其成為具名參數。
大多數情形,我們只需要傳遞一段程式 (一個block) ,所以 Ruby 提供了自動轉換 block 為 Proc 實例的機制。作為待轉換為具名參數的程式碼區塊引數,必須位於方法定義之參數列的最後一個。
如果要傳遞多段程式,則不適用上述轉換機制。程序員必須明確指示處理動作。
自動轉換 block 為 Proc 實例的機制通常應用於動態繫結的場合。
Block 與 Closure 的應用可參考 Martin 《Closure》。
樂多舊回應