亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Ruby元類混淆

Ruby元類混淆

叮當貓咪 2019-11-02 10:46:47
我知道ruby中的所有類都是元類Class的實例。而“常規”對象就是這些類的實例(元類Class的實例)。但是我一直在想,我的意思是類是對象的根,類本身是Class的實例(之所以稱為Metaclass,是因為其實例是類)。我在一些博客中看到newClass 的method的一些重載。因此,Class表現為類,但其實例是類。因此,似乎我們有一個圓圈,看起來類Class是其本身的實例。我顯然在這里漏了一點。類Class的起源是什么?這是一個使我感到困惑的示例:class Class  def new    #something  endend但是關鍵字class暗示了Class類的一個實例。那么這是如何工作的呢?
查看完整描述

3 回答

?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

這項工作如何


簡單:并非如此。無論如何,不是在Ruby中。


就像大多數其他語言一樣,有些核心實體被假定為存在。它們從天上掉下來,在稀薄的空氣中物化,神奇地出現。


在Ruby中,其中一些神奇的東西是:


Object沒有父類,但是您不能定義沒有父類的類,隱式直接父類始終為Object。[注意:可能有實現的定義的超類Object,但最終會有一個沒有超類的類。

Object是的實例Class,是的子類Object(這意味著間接Object是其Object本身的實例)

Class是的子類Module,它是的實例Class

Class 是...的實例 Class

這些事情在Ruby中都無法解釋。


BasicObject,Object,Module并且Class都需要在同一時間,因為他們有循環依賴于彈入的存在。


僅僅因為這種關系無法用Ruby代碼表達,并不意味著Ruby語言規范不能說必須如此。由實現者來決定執行此操作的方法。畢竟,Ruby實現可以訪問您作為程序員沒有的對象的級別。


例如,Ruby實現可以首先創建BasicObject,并將其superclass指針和class指針都設置為null。


然后,它創建Object,設置它的superclass指針BasicObject和class指向null。


接下來,它會創建Module,設置它的superclass指針Object和class指向null。


最后,它創建Class,設置它的superclass指針Module和class指向null。


現在,我們可以覆蓋BasicObject的,Object的,Module的,和Class的class指針指向Class,我們就大功告成了。


從系統外部很容易做到這一點,從內部看起來卻很奇怪。


但是,一旦它們確實存在,就完全有可能在純Ruby中實現大多數行為。您只需要這些類的準系統版本,這要歸功于Ruby的開放類,您可以在以后添加任何缺少的功能。


在您的示例中,class Class沒有創建名為的新類Class,而是重新打開了運行時環境提供給我們的現有類Class。


因此,完全有可能解釋Class#new純Ruby中的默認行為:


class Class

  def new(*args, &block)

    obj = allocate # another magic thing that cannot be explained in Ruby

    obj.initialize(*args, &block)

    return obj

  end

end

[注意:實際上,它initialize是私有的,因此您需要使用obj.send(:initialize, *args, &block)來規避訪問限制。]


順便說一句:這Class#allocate是另一種神奇的事物。它在Ruby的對象空間中分配了一個新的空對象,這在Ruby中是無法做到的。因此,Class#allocate運行時系統也必須提供某些東西。


查看完整回答
反對 回復 2019-11-02
?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

是的,Class是其自身的實例。它是Module的子類,也是類的實例,而Module是Object的子類,也是Object的實例。它確實是相當循環的-但這是核心語言的一部分,而不是庫中的任何內容。當我們編寫Ruby代碼時,Ruby運行時本身沒有相同的限制。


不過,我從來沒有聽說過用“元類”這個詞來談論類。在Ruby中根本沒有使用它,但是當它被使用時,它通常是正式稱為“對象的單一類”的同義詞,這是一個比Object-Module-Class三角形更令人困惑的主題。


查看完整回答
反對 回復 2019-11-02
?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

“扭曲”鏈接給出了元圓度。它是從根的本征Class類到類的內置超類鏈接。這可以表示為


BasicObject.singleton_class.superclass == Class

了解該.class映射的一個線索是看到該映射是從本征類和超類鏈接派生的:對于一個對象x,x.class是本x征類的超類鏈中的第一個類。這可以表示為


x.class == x.eigenclass.superclass(n)

其中eigenclass的“概念別名” singleton_class (可抵抗帶有立即值的問題),y.superclass(i)表示i-th的第超類,y并且n是的最小x.eigenclass.superclass(n)類。等效地,x.eigenclass將跳過的超類鏈中的本征類(請參見rb_class_real,這也表明在MRI中,甚至superclass鏈接都是間接實現的-它們是通過跳過“ iclasss ” 而產生的)。這導致class每個類別(以及每個本征類別)的始終是該Class類別。


一種圖象是通過提供該圖。


元類的混亂有兩個主要來源:


閑話。Smalltalk-80對象模型包含概念上的不一致性,這些不一致性已由Ruby對象模型糾正。此外,Smalltalk文獻在術語中使用辯證法,不幸的是,在Ruby文獻中尚未對此進行充分補救。


元類的定義。目前,該定義指出元類是class的類。但是,對于所謂的“ 隱式元類 ”(在Ruby和Smalltalk-80的情況下),更合適的定義是類的元對象。


查看完整回答
反對 回復 2019-11-02
  • 3 回答
  • 0 關注
  • 661 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號