iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
0
Software Development

Ruby 研究 30 天系列 第 20

Day 19 - Singleton Class 中篇

  • 分享至 

  • xImage
  •  

singleton class

單例類別在 Ruby 扮演了重要的角色,例如提供場所儲存類別方法及從模組引入的方法。與其他類別不同的是,他們是在有需要的時候,由 Ruby 動態建立。但它們也有若干限制,例如你無法建立單例類別的實體。這裡你唯一真的需要記得的是,單例只是沒有名稱而且有所限制的普通類別。 -- Effective Ruby

其實我們一直在說的 隱形的class 就叫做變化類別 metaclass 或是特徵類別 eigenclass ,而且這種只負責印出一個實體的 class 我們又稱為 singleton class ,並且可以用 singleton_class 方法來找出這個它。

class SuperKlass
end
class Klass < SuperKlass
end

obj_1 = Klass.new

obj_1                               # 印出 #<Klass:0x00005576e74ca1b8>
obj_1.singleton_class       # 印出 #<Class:#<Klass:0x00005576e74ca1b8>>
obj_1.singleton_class.superclass    # 印出 Klass

#<Class: instance> 這就是 singleton class 的長相。

接著我們來驗證一下繼承吧!照我們昨天的推論,隱形的 Klass 會繼承自隱形的 SuperKlass。

class SuperKlass
end

class Klass < SuperKlass
end

Klass.singleton_class                  # 印出 #<Class:Klass>
Klass.singleton_class.superclass       # 印出 #<Class:SuperKlass>

Klass.singleton_class.superclass == SuperKlass.singleton_class  # 印出 true

上面的驗證都成功,那麼我們就帥氣的一口氣叫出 Class 吧!

Klass.class
# 印出 Class ,當然不是這樣!

Klass.singleton_class.superclass.superclass.superclass.superclass
# 印出 Class

https://ithelp.ithome.com.tw/upload/images/20191122/20120823qKLzJBve8c.png

你可以說

  • 所有的 class 都是 Class 的實體。
  • 而所有 class 的 metaclass 最後都是繼承自 Class 來的。

完成了上面有趣的推論,我想大家應該都有一樣的問題:我們真的可以把這個隱形的 class 拿來操作嗎?

class Klass
end

obj_1 = Klass.new

Metaclass_1 = obj_1.singleton_class  # 幫 object_1 的 singleton class 取名字

class Metaclass_1
  def try_it
    puts "It works!!"
  end
end 

obj_1.try_it # 印出 It works!!
obj_1.singleton_methods # 印出 [:try_it]

整理一下這幾天所做的,寫出了實體的 singleton method (寫在 class 外面),並用一樣的寫法寫出了類別的 singleton method,同時發現類別方法就是一種 singleton method 。

想像一個 隱形的class ,負責裝 singleton method ,然後發現其存在的證據。因此,如果希望這個方法給不同的物件用(實體或類別都行),就找出此物件的類別,在裡面寫出方法;反之,如果希望這個方法只給一個物件用,就用 singleton method 寫吧!(或者惡搞一下叫出 singleton class ,在裡面寫一個實體方法也是可以。)

明天要把這個話題告一段落,大家可以先想想, << 是什麼意思呢!

此文同步刊登於CJ-Han的網站


上一篇
Day 18 - Singleton Class 上篇
下一篇
Day 20 - Singleton Class 下篇
系列文
Ruby 研究 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言