前情提要:
在第五天的最後,我們提到了一句話"相同的class的實體也無法使用別人的singleton method"。
在今天,我們把焦點放在Ruby的method, 繼續了解存取限制:)
說明Ruby的三種存取限制。 3 levels of access control for Ruby methods.
讓我們用Ruby程式碼分別描述三種存取:Public
, Protected
, Private
:
class TingsIronmanProcess
def publish
p "Hi guys, this is my IT article for today!"
end
protected
def mydraft
p "Hi Mentor! Please read my draft."
end
private
def myspace
p "I'm writing secretly here!"
end
end
day6 = TingsIronmanProcess.new
day6.publish # => Hi guys, this is my IT article for today!
以我自己生產第六天IT邦鐵人賽文章為例,為了防止網路斷線,或是在IT邦寫完誤按其他的鈕導致存檔出現問題,我通常在本機環境上編寫每天的主題。在這段時間要搜集素材、測試程式碼,這個過程可能會有很多生產上的秘密、需要刪除的錯誤等等之類的,過程艱辛不足為外人道矣,所以放在private
的myspace方法孤芳自賞就好。
等到文章接近完成度高、可讀性佳的地步,就放在protected
的環境,開放一些權限給它人閱讀,例如請Ruby前輩'饅頭貓'先校稿,提供修改建議。
所以如果在class
外想要取得protected
或private
方法,都會出現NoMethodError錯誤:
day6.protected #=> undefined method `protected' (NoMethodError)
day6.private #=> undefined method `private' (NoMethodError)
當一切修改完畢,就可以品嚐甜美果實,放到public
區,給大眾分享我的作品啦!
以上的類別寫法可以改成:
class TingsIronmanProcess
def publish
p "Hi guys, this is my IT article for today!"
end
def mydraft
p "Hi Mentor! Please read my draft."
end
def myspace
p "I'm writing secretly here!"
end
protected :mydraft
private :myspace
end
這種寫法,我覺得蠻類似於在開發Ruby on Rails專案上時常看到類似的架構, 哪些套件只能在開發環境development
使用,哪些在測試環境test
、哪些在正式環境production
使用的分組。
gem 'sqlite3', group: :development
gem 'pg', group: :production
如果我想把第六天的草稿send給menter看,可以把mydraft當作參數,使用send()方法,結果如下:
day6.send(:mydraft) #=> "Hi Mentor! Please read my draft."
甚至把文章連結先send給某個人看,也行:(要小心!別把不能公開的東西亂放啊!)
day6.send(:myspace) #=> "Hi guys, this is my IT article for today!
如果饅頭貓也想使用我的架構來撰寫自己的鐵人賽文章,可以繼承我的類別:
class TingsIronmanProcess
protected
def mydraft
p "Hi Mentor!"
end
private
def myspace
p "I'm writing secretly here!"
end
end
class BaterProcess < TingsIronmanProcess
def bater_draft
mydraft
end
def bater_self_draft
self.mydraft
end
end
BaterProcess.new.bater_draft # Hi Mentor!
BaterProcess.new.bater_self_draft #Hi Mentor!
在加入繼承後的新類別,我們引入昨天self
物件可以代替自身類別
的觀念。
以繼承的類別來說,在此呼叫Protected
method的方式,無論是self.mydraft
或是mydraft
,輸出結果都是Hi Mentor!
。
但如果呼叫的是Private
method myspace
呢?
class BaterProcess < TingsIronmanProcess
def bater_space
myspace
end
def bater_self_space
self.myspace
end
end
如果我們在這裡使用.self
,就會出錯:
BaterProcess.new.bater_space # => I'm writing secretly here!
BaterProcess.new.bater_self_space # => private method `myspace' (NoMethodError)
龍哥的文章說到,呼叫private
方法的時候,不能有明確的接收者。愛注意呀!
總結: 在寫鐵人賽的文章時,我都盡可能地把前幾篇的概念拿到後面來使用,增加自己觀念上的熟悉度,盡量做到具有教育意義地環環相扣。(顯示為八點檔連續劇製作人?)
在今天Day6這篇文章裡,我們把第二天繼承
和第四天self
的概念拿來測試public
、protect
和private
存取方法,也發現了:
protected :mydraft
private :myspace
:mydraft
,:myspace
這些冒號在前面的參數。
這到底是什麼呢?
明天我們就來討論符號(Symbol)
吧!:)
===
Ref: