Self <> 真正的男子漢,連道別都不需要語言!

[Day27] 就算身處絕境也要堅守自己的原則!

入秋有點涼意了,伴隨著晚風,我們不如來點小酒,聊聊有關自己的事~
今夜不醉不歸

不鬧了不鬧了這篇真的是要聊自己,不過是聊的是 Ruby 語言裡,就算天塌了也會永遠做自己的 self


self 是什麼?

之前提到類別方法時,我們就已經看過 self 了(還記得貝洛貝蒂嗎?)

1
2
3
4
5
6
7
8
9
class Army
def fight # 實體方法
puts "我要打倒天龍人!"
end

def self.inspire # 類別方法
puts "全部的人都起身戰鬥!"
end
end

self 是一種 Ruby 的虛擬變數(pseudo-variable),先來看看它屬於哪一類

1
2
self.class
=> Object

好!確定身分了!self 是個物件!

不過這個物件有點特別,self 會永遠指向當前正在執行的物件。(喔?似乎和 JavaScript 的 this 有點類似?)

在類別裡,self 代表目前的類別:

1
2
3
4
5
6
7
8
class Treasure
def self.self # 類別方法
self
end
end

Treasure.self
=> Treasure

在實體裡,self 則代表目前的實體:

1
2
3
4
5
6
7
8
def self
self
end

captain = "魯夫"

captain.self
=> "魯夫"

什麼都沒有直接用 self 會是什麼?

想知道的話我們用 who_am_i 這個方法來看:

1
2
3
4
5
6
def who_am_i
self
end

who_am_i
=> main

印出了 main !這個 main 是什麼呢?別小看它,它是 Ruby 裡層級頗高的一個物件,它也是直接隸屬於 Object 這個類別下的實體。
(原來跟 self 是同事啊!)

main 的存在非常有趣,之前提過在物件導向的概念裡,呼叫方法會需要 receiver,而 Ruby 之所以能直接呼叫方法,是因為在這個環境裡,其實已經先偷偷做好了一顆物件,因此如果沒有指定任何物件,這顆物件就會指向 main


self 可以用來區分方法和變數

在 Ruby 裡

1
2
3
4
5
6
7
8
9
10
11
12
13
class Pirate
def supernew
"最惡世代"
end

def difference
supernew = "超新星"
puts supernew # 印出變數
puts self.supernew # 印出實體方法
end
end

Pirate.new.difference

在 Ruby 裡,同時存在同名的變數和方法時,會以變數優先,但若真的需要呼叫方法,而需要忽略變數的話,可以使用 self 來達成。


也可以把 self 當作回傳值使用

肚子有點餓了,想吃個點心:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Snack
attr_accessor :bowl

def initialize
@bowl = []
end

# 把穀片倒入碗裡
def add_cereal
@bowl << :cereal
self
end

# 把牛奶倒入碗裡
def add_milk
@bowl << :milk
self
end

# ... 其他點心
end

現在來盛一碗享用吧!

1
my_snack = Snack.new.add_cereal.add_milk

來看看碗裡有什麼:

1
2
3
4
my_snack.bowl

# 印出
[:cereal, :milk]

嗯~太棒了!是我喜歡的穀片 + 牛奶~開動!(嚼嚼嚼)


今天就先到這邊啦~真的嘴饞打算去吃個點心
而且關於自己的事也不好講太多(

如果想了解更多 Ruby 的 self ,網路上有更多大大們分享的精彩文章,都非常值得一看喔!


參考來源

  1. 尋找自己: Ruby 的 self 物件與 singleton method
  2. 什麼是 Self & 怎麼使用它
  3. Ruby 裡的 self 是什麼意思
  4. Ruby self 與作用域
  5. Ruby 中的 self 變數以及應用
  6. Ruby 初心者的學習筆記 2:難以捉摸的 self
  7. Ruby 裡的 self 是什麼意思