最近更新: 2012-04-24

Introspection and Reflection in Programming Language

網友在另一篇文章的回應中,問我程式語言中的自識與反射有何區別。 關於反射與自識,我的說法是「Reflection 一般譯為反射,但我稱為自識的能力」。見「什麼是 Reflection?」。

「反射」,或稱「反映」,對應英文 reflect;「自識」,或稱「內省」,對應英文 introspect 。 在程式語言中,這兩者基本上指的是同一件事,即個體認知自身的能力,讓 object 看到自己的外貌的功能。 但是 reflect 與 introspect 的語義,表達了兩種方式的差異在於認知途徑不同。 也就是說,反射能力就是自識能力,差別在語義不同。

有些程式語言採用要個體先拿一面鏡子,亦即反射體(reflector),透過這面鏡子才能看到自己樣貌的認知途徑,例如Java、C#。「反射」、「reflect」的語義就是要表達這個情境。

另一方面,有些程式語言不需要一面鏡子、一個反射體,就可以讓個體認識自己。這種情形使用「自識」、「introspect」的語義。由於不存在反射體,稱「反射」就不符合情境。

有趣的是,基於歷史因素,PHP 兩種途徑都支援。它一開始是自識途徑。後來 Java 普及到資訊教育體系之後,為了吸引那些學生使用 PHP,故 PHP 引入了許多 Java 的項目,這其中就包含了反射。就形成了如今兩種途徑並存的情形。

既然 PHP 兩種途徑都支援,那麼用它來說明兩種途徑的形式差異再好不過了。 下列程式碼示範了最基本的認知自身現有屬性的動作。 兩種途徑並列,讓人一眼就能理解什麼是認知途徑的差異。

class A {
    var $title = 'abc';
}

$a = new A();

/* Introspect, 直接的自我認知 */
foreach ($a as $prop => $value) {
    echo $prop, ': ', $value, "\n";
}

/* Reflect, 拿鏡子看自己 */
$ref_a = new ReflectionObject($a);
foreach ($ref_a->getProperties() as $prop_reflector) {
    $prop = $prop_reflector->name;
    $vavlue = $a->$prop; //$value = $prop_reflector->getValue($a);

    echo $prop, ': ', $value, "\n";
} 

就目前已知的程式語言來看,採用反射途徑的程式語言,其個體的自識能力都比較低下,使用比較不方便。從上列範例的程式碼,應該不難看出為何我說使用不方便。

附帶一提,像 GetTypetypeof 這些查知個體型態的方法,只是自識能力中最基本的項目。如果要列一張各種程式語言自識能力的評比表,它甚至還不會被列入評比項目。

樂多舊網址: http://blog.roodo.com/rocksaying/archives/19362490.html

樂多舊回應
yurenju@gmail.com(Yuren Ju) (#comment-22427490)
Tue, 24 Apr 2012 14:35:49 +0800
你對 GJS 了解蠻多的耶,不考慮在 COSCUP 講一場相關主題的?
這個領域的講題在台灣很少

我看了一下在台灣有在關注我又認識的就只有你、我跟 Fred XD
未留名 (#comment-22427596)
Tue, 24 Apr 2012 16:05:41 +0800
嗯... 你回錯主題了。
我搬到前一篇主題回應。
lungzenoopen@gmail.com(LungZeno) (#comment-22427620)
Tue, 24 Apr 2012 16:29:15 +0800
不好意思,又來 challenge 了。

可能因為我放了太多連結,所以被誤判為 spam 。

我改為貼上 pastebin : http://pastebin.com/6r7LtkpC
未留名 (#comment-22427688)
Tue, 24 Apr 2012 17:30:21 +0800
在程式語言中,reflection 譯為反射是誤譯這點,我認同。我也始終認為 object 應該譯為個體,而不是物件。object譯為個體並非我獨創,而是十幾年前台灣資策會在推廣OOP時的用法。但同字習慣已經形成,也就隨它去了。反正我是不用的。

這篇 http://coding.derkeiler.com/Archive/Lisp/comp.lang.lisp/2005-09/msg01064.html 作者的說法其實和我沒什麼差別,我們都認識到不論是用 reflect 或是 introspect ,在電腦科學中,都是指同一件事。我的第一篇文章就沒有特意區別兩者,我的作法是「寫成reflection,讀成自識」。

另一方面,許多人第一次接觸 reflection 這個觀念是在學習 Java 或 C# 時。由於他們的學習經驗太強烈,以至於他們往往誤會只有符合 Java/C# 那種表達形式的作法才叫 reflection,因此認為其他語言不具有這種能力。又或是把 introspection 當成另一種觀念。

所以我在這篇文章從中文與英文的基本語義著手,加上使用形式的差異,解釋為什麼有人說 introspection,有人則說 reflection。

引用文章的作者認為 reflection 包含 introspection 和 intercession 兩種意涵,可以說是他的個人解釋,但也可以視為在電腦科學的條目中,人們漸漸認為 reflection 的語義已經概括兩者(僅限電腦科學)。

我個人的習慣是,如果我在談 python, ruby 這類程式語言的內容時,我會用 introspection 。當我在談 Java, C# 的內容,則用 reflection 。無所謂對錯,只是配合使用族群的用字習慣罷了。