2008年3月9日

REBOL函數的複製與否

文 / 蔡學鏞

對於大多數的物件導向語言來說(包括C++、Java、C#),實體方法(instance method)一定會被傳進一個隱匿的參數(implicit parameter),當作方法的第一個參數,此參數正是此物件實體。大多數的語言,都稱此參數為this。

在實體方法內,如果沒有指明呼叫的方法是由誰所提供,就相當於在前面加上「this.」。因此呼叫myMethod(),就相當於呼叫this.myMethod()。語言這麼設計的好處是,不管new出多少個實體,這些實體方法都只需要一份,節省相當多記憶體。

REBOL物件內的函式,雖然可以使用self參考到物件本身(self類似於其他語言的this),但是self是被繫結(binding)到函式內的,並不是被當成隱匿的參數傳入的。事實上,不只self,該物件context會整個被繫結到函式內。因此,產生新物件時(REBOL產生物件的方式是「複製」),如果只有複製資料,沒有複製物件內的函式(使用COPY obj),會造成新物件的函式依然參考到舊的物件,造成奇怪的後果。如果連同函式一起複製,並將新函式重新繫結到新物件,就不會有這樣的後果(使用MAKE obj [] )。

但是這麼做會浪費相當多記憶體,所以另一種比較常見的作法是將這些函式都獨立出來,不要放在物件內。為這些函式都加上一個物件參數,好將它們要處理的物件傳遞進來。這樣的設計相當於走回C語言常用的設計方式。當然,REBOL社群會比較建議採用這種方式,因為REBOL人對於無謂的浪費是相當在意的。