Perl 6 中的元對(duì)象協(xié)議

自省和 Perl 6 的對(duì)象系統(tǒng)


Perl 6 是構(gòu)建在元對(duì)象層上面的稳诚。那意味著有些對(duì)象(元對(duì)象)控制著各種面向?qū)ο蠼Y(jié)構(gòu)(例如類贱除、roles、方法诀诊、屬性、枚舉,…)怎樣去表現(xiàn)阅嘶。

要感受類的元對(duì)象, 這兒有一個(gè)同樣的例子出現(xiàn)2次: 一次一種 Perl 6中的普通聲明, 一次通過元模型來表達(dá):

class A {
    method x() { say 42 }
}
A.x(); # 42

對(duì)應(yīng)于:

constant A := Metamodel::ClassHOW.new_type( name => 'A' );  # class A {
A.^add_method('x', my method x(A:) { say 42 });             # method x() .. .
A.^compose;                                                 # }

A.x(); # 42

(除了聲明形式的運(yùn)行在編譯時(shí), 后面這種形式不是)

對(duì)象后面的元對(duì)象能使用 $obj.HOW獲取, 這兒的 HOW 代表著 Higher Order Workings(或者 HOW the *%@$ does this work?)属瓣。

這兒, 帶有 .^的調(diào)用是元對(duì)象的調(diào)用, 所以 A.^composeA.HOW.compose(A)的簡(jiǎn)寫。調(diào)用者也被傳遞到參數(shù)列表中, 以使它能夠支持原型類型風(fēng)格的類型系統(tǒng), 那兒只有一個(gè)元對(duì)象讯柔。

就像上面的例子展示的那樣, 所有的面向?qū)ο筇匦詫?duì)使用者都是可獲得的, 而不僅僅是編譯器抡蛙。實(shí)際上編譯器就是使用元對(duì)象的這樣的調(diào)用的。

元對(duì)象(MetaObjects)


這些是內(nèi)省的宏, 類似于方法調(diào)用魂迄。

元對(duì)象通常以 ALLCAPS(全大寫)命名, 并且避免使用你自己的帶有全大寫名字的方法被認(rèn)為是一個(gè)好的風(fēng)格粗截。這會(huì)避免和可能出現(xiàn)在未來版本中的任何元對(duì)象發(fā)生沖突。注意, 如果你必須使用帶有全大寫名字的方法的話, 把你的這個(gè)方法名字用引號(hào)引起來來間接安全地調(diào)用:

#| THIS IS A CLASS FOR SHOUTING THINGS
class MY-CLASSES-ARE-ALL-CAPS {
    method WHY { "I DON'T KNOW" }
}
my $c = MY-CLASSES-ARE-ALL-CAPS.new;
say $c.WHY      # "THIS IS A CLASS FOR SHOUTING THINGS"? 顯示這?你在逗我!
say $c."WHY"()  # "I DON'T KNOW"

WHAT


類型的類型對(duì)象台妆。例如 42.WHAT 返回 Int類型對(duì)象。

WHICH


對(duì)象的同一值胳徽。這能用于哈希和同一比較, 并且這是 ===中綴操作符的實(shí)現(xiàn)方式婿屹。

> "a".WHICH
Str|a

WHO


支持對(duì)象的包

> "a".WHO
Str

WHERE


對(duì)象的內(nèi)存地址灭美。注意這在移動(dòng)的/緊湊的垃圾回收實(shí)現(xiàn)中是不穩(wěn)定的。 在穩(wěn)定的同一指示器中使用 WHERE昂利。

HOW


元類對(duì)象(the metaclass object):“Higher Order Workings”届腐。

WHY


附加的 Pod 值。

DEFINITE


對(duì)象有一個(gè)有效的強(qiáng)制表現(xiàn)蜂奸。

對(duì)于實(shí)例返回 True, 對(duì)于類型對(duì)象返回 False犁苏。

> 42.DEFINITE
True
> Int.DEFINITE
False

VAR


返回底層的 Scalar 對(duì)象, 如果有的話。

元對(duì)象系統(tǒng)的結(jié)構(gòu)


對(duì)于每個(gè)類型聲明符關(guān)鍵字, 例如 class扩所、role 围详、enummodule碌奉、package短曾、grammarsubset, 就有一個(gè)獨(dú)立的元類在 Matamodel::命名空間中。(Rakudo 在 Perl6::Metamodel::命名空間中實(shí)現(xiàn)了它們, 然后把 Perl6::Metamodel映射到 Metamodel)赐劣。

這些元類(meta classes)中的很多都共享公共的功能。例如 roles哩都、grammars和 classes(類)都能包括方法和屬性, 還能遵守 roles魁兼。這個(gè)共享的功能是在 roles 中實(shí)現(xiàn)的, 它被組合進(jìn)合適的元類中。例如 role Metamodel::RoleContainer實(shí)現(xiàn)了類型能處理 roles 和 Metamodel::ClassHOW的功能, 它是在 class關(guān)鍵字后面的元類, 遵守了這個(gè) role漠嵌。

Bootstrapping concerns


你可能想知道為什么 Metamodel::ClassHOW可以是一個(gè)類, 當(dāng)按照Metamodel::ClassHOW作為一個(gè)類被定義時(shí), 或者 roles 負(fù)責(zé) role 處理的怎么能是 roles咐汞。答案是通過魔法。

開玩笑啦儒鹿。自舉是特別實(shí)現(xiàn)的化撕。Rakudo 使用語言的對(duì)象系統(tǒng)來實(shí)現(xiàn)自舉, 它恰好(幾乎)就是 Perl 6 的一個(gè)子集: NQP, Not Quite Perl。 NQP 有原始的, class-like 叫做 konwhow 的性質(zhì), 它用于自舉它自己的類和 roles 實(shí)現(xiàn)约炎。konwhow建立在NQP 提供的虛擬機(jī)的原始基礎(chǔ)上植阴。

因?yàn)樵獙?duì)象是根據(jù)低級(jí)(low-level)類型引導(dǎo)的, 自省有時(shí)能返回低級(jí)(low-level)類型而非你期望的那個(gè)類型, 例如返回一個(gè) NQP-level 的子例程而非普通的 Routine對(duì)象, 或返回一個(gè)引導(dǎo)的屬性而非Attribute

組合和靜態(tài)推理


在 Perl 6中, 類型是在解析時(shí)被構(gòu)造的, 所以在開始, 它必須是可變的圾浅。然而, 如果所有類型一直是可變的, 那么關(guān)于類型的所有推斷會(huì)在任何類型的修改時(shí)變得無效掠手。例如父類的列表因此類型檢測(cè)的結(jié)果能在那個(gè)時(shí)候改變。

所以為了獲得這兩個(gè)世界中最好的東西, 當(dāng)類型從可變轉(zhuǎn)為不可變時(shí)是好時(shí)機(jī)狸捕。這就叫做組合, 并且對(duì)于從句法構(gòu)成上聲明的類型, 它發(fā)生在類型聲明被完全解析時(shí)(所以總是在閉合花括號(hào)被解析時(shí))喷鸽。

如果你通過元對(duì)象系統(tǒng)直接創(chuàng)建類型, 你必須要在它們身上調(diào)用 .^compose, 在它們變得完全起作用之前。

很多元類也使用組合時(shí)來計(jì)算一些諸如方法解析順序這樣的屬性, 發(fā)布一個(gè)方法緩存, 和其它清掃任務(wù)灸拍。在它們被組合之后干預(yù)類型有時(shí)是可能的, 但通常是造成災(zāi)難的因素做祝。 不要那樣做砾省。

能力和責(zé)任


元對(duì)象協(xié)議提供了很多常規(guī) Perl 6 代碼故意限制了的能力, 例如調(diào)用類中不信任你的私有方法, 窺探私有屬性, 和其它通常不能完成的東西。

常規(guī)的 Perl 6 代碼有很多就地的安全檢測(cè); 元模型中不是這樣混槐,它靠近底層的虛擬機(jī), 違反和虛擬機(jī)的約定可以導(dǎo)致所有奇怪的行為, 而在正常代碼中, 顯而易見的會(huì)是 bugs编兄。

所以, 在寫元類型的時(shí)候要格外小心和思考。

能力纵隔、便利和陷阱


元對(duì)象協(xié)議被設(shè)計(jì)的強(qiáng)大到實(shí)現(xiàn) Perl 6 的對(duì)象系統(tǒng)翻诉。這種能力間或花費(fèi)了便利的代價(jià)。

例如, 當(dāng)你寫了 my $x = 42并在 $x上調(diào)用方法時(shí), 大部分方法會(huì)在整數(shù) 42 上起作用, 而不是在存儲(chǔ) 42 的標(biāo)量容器上捌刮。這是 Perl 6中設(shè)立的一塊便利碰煌。元對(duì)象協(xié)議中的大部分不能提供自動(dòng)忽略標(biāo)量容器的便利性, 因?yàn)樗鼈円灿糜趯?shí)現(xiàn)那些標(biāo)量容器。 所以, 如果你寫了 my $t = MyType; ... $t.^compose, 那么你正組合那個(gè)$變量表明的標(biāo)量, 而不是 MyType绅作。

結(jié)果就是你需要很詳盡的理解 Perl 6 的底層以避免陷阱, 當(dāng)使用 MOP 時(shí), 并且不能期望得到和普通 Perl 6 代碼提供的 "do what I mean" 的便利芦圾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俄认,隨后出現(xiàn)的幾起案子个少,更是在濱河造成了極大的恐慌,老刑警劉巖眯杏,帶你破解...
    沈念sama閱讀 212,185評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夜焦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岂贩,警方通過查閱死者的電腦和手機(jī)茫经,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,445評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萎津,“玉大人卸伞,你說我怎么就攤上這事★鼻” “怎么了荤傲?”我有些...
    開封第一講書人閱讀 157,684評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)颈渊。 經(jīng)常有香客問我遂黍,道長(zhǎng),這世上最難降的妖魔是什么儡炼? 我笑而不...
    開封第一講書人閱讀 56,564評(píng)論 1 284
  • 正文 為了忘掉前任妓湘,我火速辦了婚禮,結(jié)果婚禮上乌询,老公的妹妹穿的比我還像新娘榜贴。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,681評(píng)論 6 386
  • 文/花漫 我一把揭開白布唬党。 她就那樣靜靜地躺著鹃共,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驶拱。 梳的紋絲不亂的頭發(fā)上霜浴,一...
    開封第一講書人閱讀 49,874評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音蓝纲,去河邊找鬼阴孟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛税迷,可吹牛的內(nèi)容都是我干的永丝。 我是一名探鬼主播,決...
    沈念sama閱讀 39,025評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼箭养,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼慕嚷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毕泌,我...
    開封第一講書人閱讀 37,761評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤喝检,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后撼泛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挠说,經(jīng)...
    沈念sama閱讀 44,217評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,545評(píng)論 2 327
  • 正文 我和宋清朗相戀三年愿题,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纺涤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,694評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抠忘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出外永,到底是詐尸還是另有隱情崎脉,我是刑警寧澤,帶...
    沈念sama閱讀 34,351評(píng)論 4 332
  • 正文 年R本政府宣布伯顶,位于F島的核電站囚灼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏祭衩。R本人自食惡果不足惜灶体,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,988評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掐暮。 院中可真熱鬧蝎抽,春花似錦、人聲如沸路克。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,778評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瓢宦,卻和暖如春碎连,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背驮履。 一陣腳步聲響...
    開封第一講書人閱讀 32,007評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工鱼辙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玫镐。 一個(gè)月前我還...
    沈念sama閱讀 46,427評(píng)論 2 360
  • 正文 我出身青樓倒戏,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親摘悴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峭梳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,580評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 2009 有用的和有意思的循環(huán) 讓我們來看一個(gè)基本的例子. 這是一個(gè)最簡(jiǎn)單清晰的語法的例子.在這并沒有使用括號(hào)來包...
    焉知非魚閱讀 540評(píng)論 0 0
  • 標(biāo)題: Rakudo and NQP Internals子標(biāo)題: The guts tormented imple...
    焉知非魚閱讀 1,360評(píng)論 1 3
  • 2016-10-20 號(hào)更新。 源文件可以在 github 或 perl6.org上找到. General Rak...
    焉知非魚閱讀 974評(píng)論 0 0
  • 從匹配中返回值 Match 對(duì)象 成功的匹配總是返回一個(gè) Match 對(duì)象, 這個(gè)對(duì)象通常也被放進(jìn) $/ 中, (...
    焉知非魚閱讀 1,792評(píng)論 0 1
  • Object Orientation in Perl 6 Perl 6 有很多預(yù)先定義好的類型蹂喻,這些類型可以歸為 ...
    焉知非魚閱讀 459評(píng)論 0 1