2008年6月18日

小心TO-BLOCK的陷阱

許多REBOL函數的參數都同時接受單一值,或多重值。當然多重值會放在block中。我們經常會需要在函數內,先將某參數化成block,然後才進行處理,這時候程式會這麼寫。

if not block? :args [args: reduce [:args]]

透過to-block(或者to block!),可以簡化上面的作法,改寫成這樣:

args: to-block :args

to-block會判斷,如果後面的參數是any-block!,則不處理,直接傳出其block形式;如果參數不是any-block!,則傳出以該參數為「唯一」元素的block。如下所示:

>> to-block 1
== [ 1 ]
>> to-block [ 1 ]
== [ 1 ]

To-block確實相當方便,但是要注意一個特殊狀況,那就是any-block!除了block!之外,還包括其他:

>> ? any-block!
ANY-BLOCK! is a typeset of value: make typeset! [block! paren! map! path! set-pa
th! get-path! lit-path! ]

因此下面的狀況固然可能非你所願,但卻是正確的:

>> to-block 'system/version
== [ system version ]

這個時候,只好回去改用一開始的寫法:

if not block? :args [args: reduce [:args]]

沒有留言: