photo by Brad Higham
之前在 Public, Protected and Private Method in Ruby 這篇文章提到,在 Ruby 裡使用 private 方法的時候,不能明確的指出 receiver,以下面這段範例來說:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
在上面這段程式碼的第 13 行,因為它明確的指出 receiver (snoopy),所以執行這行程式碼會出現會出現 NoMethodError 的錯誤;而在第 3 行,即使 receiver 是 self 也一樣是不行的。
這是在 Ruby 裡面 private 方法的設計。
不過,今天剛好有朋友拿了一段程式碼給我看,才發現原來上面這個規則原來也是有例外的,舉個例子來說:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
在上面這段範例中用 attr_accessor 做了一個 name 的 getter 跟 setter,並且把 getter/setter 設定成 private。在第 10 行的地方呼叫了 private 的 getter,並且明確的指出 receiver 是 self,照規則來說會出現錯誤不意外,但第 14 行用類似的方法呼叫了 private 的 setter 卻沒有出錯!
的確 private 方法不能指出明確的 receiver,但 setter 算是這個規則的例外。因為你不在前面加 self 的話,像這樣:
1 2 3 | |
這樣這個 name 不就變成區域變數的賦值了嗎?
想想看,如果在這裡呼叫 setter 不加 self 的話,那 Ruby 要怎麼分辨到底你是要呼叫 setter 還是區域變數?
話說回來,通常我們也不會沒事把 getter/setter 設定成 private,因為既然都做了 getter/setter 就是要給別人用的不是嗎? :)