本篇將介紹在 Ruby 的世界裡的 Self 是什麼?
" Whenever you get stuck if you are doing meta programming, and you get stuck trying to workout how come that's nil, I guarantee you that if you track the value of self, you'll understand it " from Dave Thomas
Self 在 Ruby 的世界裡可以被理解為 "當下執行的物件(current object)",但是如何才能看出(current object)為何呢?在多數的情況下,當呼叫方法的時候,訊息接收者(receiver )會變成 self ,因此通常可從最後呼叫的方法,來找到 self。
以上面程式碼為例:
當我們呼叫 speak() 方法的時候,『訊息的接收者』為 cat 這個實體物件,也就是當下執行的物件 self,
@age 是 cat 的實體變數,因此在行數 4 可以看到 @age 會顯示數字 5。
接者執行 count() 此時,self 維持不變,也就是說 @age ㄧ樣是 cat 的實體變數
找到 count() 執行第10行後,回傳數字 6 在第 5 行。
然而, self 在以下兩種例外情況則需要特別地注意:
此物件當下是在 ruby 執行環境下的最頂層,有可能是還沒有開始呼叫 method 或者是所有的 method 都已經執行完成。
參考自 Metaprogramming Ruby
當 self 在類別(class)或模組(module)時,self 會依所在的位置不同而改變。
以上面的程式碼來說,雖然第3行的 @size 是已經定值為 3,我們從第2行可得知這裡的 self 是 Animal,因此不難看出第3行的 @size 也是屬於 Animal class。
在第 8 行的 @size 會列出 nil ,其原因就是當 self 走到第8行時,self 是 cat 這個物件,而 speak() 方法內的 @age 和 @size 都是 cat 的 instance variables,因為只有 @age 被賦值 5, 因此 @size 會是 nil。
self 就是當下執行的物件,通常就是方法的『訊息的接收者』
self 在執行環境頂層、類別(class) 或是 模組(module)時,self 會依所在的位置不同而改變
Reference: The Ruby Object Model by Dave Thomas