What have you found for these years?

2011-04-13

R: [問題] 關於Ruby的多型

ptt ruby 板久違的 post 耶,特此紀念...

 作者 godfat (godfat 真常) 看板 Ruby
 標題 Re: [問題] 關於Ruby的多型
 時間 Wed Apr 13 02:36:45 2011
───────────────────────────────────────

你想做的事情,一般會叫做 overloading, 不過要說 polymorphism,
也是有人用 ad-hoc polymorphism 來形容:

    http://en.wikipedia.org/wiki/Ad-hoc_polymorphism

而 ruby 之所以沒辦法做 overloading 的原因是,對於 ruby 來說,
compile time 跟 runtime 幾乎可以說是同一件事。我們知道 overloading
是靠 argument type 來決定 compile time 的 function binding,
也就是說,compile 完畢後,其實程式就知道實際上呼叫的是哪個 function.

然而 ruby 卻在執行時,也可能改變呼叫的 function 的對象,
這和 overloading 本身是相違背的,因此這兩件事不能同時成立...

也就是說,在 ruby 裡,一個 function (method) 只能有一個 name.
你那樣寫應該不會有錯誤,就只是前者的 method 被後者的 method
取代而已,也就等同於前者的 method 完全不存在似的。

    * 以下完全離題,跟 ruby 無關

而事實上,overloaded function 的實作,也不是讓他們真的是同一個名字。
在 compiler 把 overloaded function compile 好後,實際上這 function 的
真正名字會是另外一個,以此區別原本同名的 function. 這個動作叫
name mangling:

    http://en.wikipedia.org/wiki/Name_mangling

不同 compiler 可能會有不同的 mangling 方式,這會使得 ABI 變成一種問題——
例如 A compiler 把 int f(int) 的名字變成 int_f_int, 而 B compiler 把
int f(int) 的名字變成 i_f_i, 使得 compiled 好的結果不一致,導致不同
compiler 產生出來的 binary 各不相容。

    http://en.wikipedia.org/wiki/Application_binary_interface

    * 回到 ruby

事實上,在 ruby 裡想真的實作 overloading 也是要靠 mangling. 實不相瞞,
我自己也試著做過。大抵上寫起來會像是:

    def_overloaded_method :initialize do |szTag|
      # ...
    end

    def_overloaded_method :initialize do |szTag, szValue|
      # ...
    end

然後 def_overloaded_method 會定義一個 initialize, 內容則是判斷傳進去的
參數是什麼,然後重新呼叫 mangled function (e.g. initialize_szTag
or initialize_szTag_szValue).

實際上可能得做得比這個要更複雜,這邊只是正好你的參數數量不同,
因此可以靠 arity 來判斷實際上是哪個 function. 如果是要依靠 argument type,
那這邊就變成定義 function 時本身需要寫 type.

總而言之,這種事情玩過就好了,實務上不可能會這樣用的...

--
「行け!Loki!」(rocky ロッキー)

        -Gurumin ぐるみん 王子? XD

--
※ 發信站: 批踢踢實業坊(ptt.cc)

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0