" Here is possibly the most important thing you'll never learn about the Ruby object model: classes themselves are nothing but objects." from Metaprogramming Ruby
在 Ruby Object model 裡,類別 (Class) 其實也是實例化的物件(Object) 。
"Kevin".class # => String Class
String.class # => Class
先前提過的物件 (Object) 特性: 實例變數是住在實例物件裡面,而方法卻是住在類別
實例物件 (instance object) 的方法是定義在類別 (Class) 裡,而 Class 也是實例化的物件。因此 這些方法也是該類別 (Class) 的實例方法 (instance methods)。
"Kevin".class # => String Class
String.class # => Class
Class.class # => Class
Class.instance_methods(false) # => [:allocate, :superclass, :new]
從 Class.instance_methods(false) 可得知屬於類別自己而不是繼承來的方法為:allocate、superclass、 new 。其中最常見的就是 new 方法了,而 superclass 方法則是用來取得繼承的父類別
也許讓很多人驚訝的是類別其實是繼承自模組,也就是說每個 class 也都是 module。
Class.superclass # => Modul
Class.instance_methods(false) # => [:allocate, :superclass, :new]
還記得剛剛提到的 3 個 Class 的實例方法:[:allocate, :superclass,:new],我們可以這樣說 Class 就是繼承自 Module 再加上 3 個以上實例方法。在許多的情況下,選擇使用 Class 還是 Module 的界線並不是那麼清楚。通常可以依照該程式碼區塊是否有擴展、繼承或是有實例化的需求,來作為考量的基礎。
在 Ruby 的世界中,類別與模組都必須以常數命名,其規定也很簡單,就是必須以英文大寫開頭。
嚴格來說,其實常數與變數的差別並不是很顯著,因為常數也是可以被修改的(只是會收到警告訊息而已!) 。兩者之間最重要的不同之處在於它們的作用範圍。由於 Ruby 編排所有常數的方式類似我們熟悉的檔案系統:類別或是模組比擬資料夾,而常數就相同於檔案。
以上面程式碼來說,常數的編排方式會如下圖:
也就是說即使影片名稱都ㄧ樣命名為 Favorite, 如果我要看美國的限制級戰警,點選在USA資料夾內的 Favorite 影片才是正確的, 如果點到JP資料夾內的 Favorite 影片檔,就會是別的影片了。在 Ruby 中常數也是如此,要得到 "XXX" 在類別 JP 就必須得用『路徑』來區分並取得 Favorite 常數的值。
在 irb 裡便可看出需要以標示路徑 MyMovie::USA::Favorite 來取得正確的值。