iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 5
0
自我挑戰組

Metaprogramming Ruby and Rails系列 第 5

Day 5 -- The Truth About Classes

" 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 方法則是用來取得繼承的父類別

Module (模組)

也許讓很多人驚訝的是類別其實是繼承自模組,也就是說每個 class 也都是 module。

Class.superclass                   # => Modul 
Class.instance_methods(false)  # => [:allocate, :superclass, :new]

還記得剛剛提到的 3 個 Class 的實例方法:[:allocate, :superclass,:new],我們可以這樣說 Class 就是繼承自 Module 再加上 3 個以上實例方法。在許多的情況下,選擇使用 Class 還是 Module 的界線並不是那麼清楚。通常可以依照該程式碼區塊是否有擴展、繼承或是有實例化的需求,來作為考量的基礎。

Constant (常數)

在 Ruby 的世界中,類別與模組都必須以常數命名,其規定也很簡單,就是必須以英文大寫開頭。
https://ithelp.ithome.com.tw/upload/images/20200920/20120868kOOTryCupC.png
嚴格來說,其實常數與變數的差別並不是很顯著,因為常數也是可以被修改的(只是會收到警告訊息而已!) 。兩者之間最重要的不同之處在於它們的作用範圍。由於 Ruby 編排所有常數的方式類似我們熟悉的檔案系統:類別或是模組比擬資料夾,而常數就相同於檔案。
https://ithelp.ithome.com.tw/upload/images/20200920/20120868LDxM4hQPp3.png
以上面程式碼來說,常數的編排方式會如下圖:
https://ithelp.ithome.com.tw/upload/images/20200920/20120868lAp3oMXA9z.png
也就是說即使影片名稱都ㄧ樣命名為 Favorite, 如果我要看美國的限制級戰警,點選在USA資料夾內的 Favorite 影片才是正確的, 如果點到JP資料夾內的 Favorite 影片檔,就會是別的影片了。在 Ruby 中常數也是如此,要得到 "XXX" 在類別 JP 就必須得用『路徑』來區分並取得 Favorite 常數的值。

在 irb 裡便可看出需要以標示路徑 MyMovie::USA::Favorite 來取得正確的值。

重點回顧

  • 類別也是物件
  • 類別繼承自模組並擁有 3 個實例方法:new()、superclass()、allocate()
  • 英文字母大寫開頭都是常數
  • 常數是以自己獨特的路徑來區分及取值

上一篇
Day 4 -- Inside the Object Model
下一篇
Day 6 -- What is Self in Ruby's World ?
系列文
Metaprogramming Ruby and Rails33

尚未有邦友留言

立即登入留言