作者godfat (godfat 真常)
看板Ruby
标题Re: [问题] 关於Ruby的多型
时间Wed Apr 13 02:36:45 2011
※ 引述《ireullin (raison detre)》之铭言:
: 小弟最近刚开始接触Ruby
: 所以有些语法还不太熟
: 下面这样写执行时会发生错误
: 请问Ruby没有提供多型的功能嘛
: 还是只有建构式如此呢
你想做的事情,一般会叫做 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)
◆ From: 220.135.160.129