iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1
Modern Web

30天修煉Ruby面試精選30題系列 第 6

Day06 - Ruby三種存取限制: Public, Protected, Private

  • 分享至 

  • xImage
  •  

前情提要:

第五天的最後,我們提到了一句話"相同的class的實體也無法使用別人的singleton method"。

在今天,我們把焦點放在Ruby的method, 繼續了解存取限制:)


Ruby經典面試題目 #06

說明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外想要取得protectedprivate方法,都會出現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的概念拿來測試publicprotectprivate存取方法,也發現了:

protected :mydraft
private :myspace
:mydraft:myspace 這些冒號在前面的參數。

這到底是什麼呢?

明天我們就來討論符號(Symbol)吧!:)

===

Ref:


上一篇
Day05 - 尋找自己: Ruby的self物件與singleton method
下一篇
Day07 - Ruby比一比: Symbol符號與String字串
系列文
30天修煉Ruby面試精選30題31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Bater
iT邦新手 4 級 ‧ 2018-10-09 17:43:20

我有在面試的時候被問過這題喔,是很基本又很重要的觀念喔!

我要留言

立即登入留言