Ruby有通過使用鍵,如爲什麼使用Ruby的attr_accessor,attr_reader和attr_writer?
attr_accessor :var
attr_reader :var
attr_writer :var
我爲什麼會選擇attr_reader
或attr_writer
共享實例變量,如果我可以簡單地使用attr_accessor
這個方便和便捷的方式?有沒有像表現(我懷疑)?我猜這是有原因的,否則他們不會做出這樣的關鍵。
Ruby有通過使用鍵,如爲什麼使用Ruby的attr_accessor,attr_reader和attr_writer?
attr_accessor :var
attr_reader :var
attr_writer :var
我爲什麼會選擇attr_reader
或attr_writer
共享實例變量,如果我可以簡單地使用attr_accessor
這個方便和便捷的方式?有沒有像表現(我懷疑)?我猜這是有原因的,否則他們不會做出這樣的關鍵。
您可以使用不同的訪問器將您的意圖傳達給讀取您的代碼的人,並且可以更輕鬆地編寫無論公用API如何調用都能正常工作的類。
class Person
attr_accessor :age
...
end
在這裏,我可以看到,我可以讀取和寫入的年齡。
class Person
attr_reader :age
...
end
在這裏,我可以看到,我可能只能閱讀年齡。想象一下,它是由這個類的構造函數設置的,之後保持不變。如果有一個年齡增長的變種(作家),並且這個班級是在假設年齡的情況下編寫的,那麼一旦設置,年齡不會改變,那麼代碼調用該變種可能會導致一個錯誤。
但幕後發生了什麼?
如果你寫:
attr_writer :age
這被翻譯成:
def age=(value)
@age = value
end
如果你寫:
attr_reader :age
這被翻譯成:
def age
@age
end
如果你寫:
attr_accessor :age
這被翻譯成:
def age=(value)
@age = value
end
def age
@age
end
知道了,這裏是另一種方式來想一想:如果你沒有足夠的ATTR _...幫手,和必須自己編寫訪問器,你會寫更多的訪問器嗎?例如,如果只需要閱讀年齡,您是否也會編寫一個允許寫入的方法?
您並不總是希望您的實例變量可以從課程外部完全訪問。有很多情況下允許讀取一個實例變量是有意義的,但寫入它可能不會(例如,從只讀源檢索數據的模型)。有些情況下,你想要的是相反的,但我想不出任何不屬於我的頭腦的東西。
簡單易懂 – 2015-07-17 20:38:59
並非對象的所有屬性都是從課外直接設置的。爲所有實例變量編寫代碼通常是弱封裝的標誌,並且警告您在類之間引入了過多的耦合。
作爲一個實際的例子:我寫了一個設計程序,將物品放入容器中。這個項目有attr_reader :container
,但是提供一個作者是沒有意義的,因爲項目容器應該改變的唯一時間是當它被放入一個新的時候,這也需要定位信息。
瞭解訪問者限制對變量的訪問權限,而不是他們的內容是很重要的。在Ruby中,就像其他一些OO語言一樣,每個變量都是一個指向實例的指針。所以,如果你有一個哈希屬性,並且你將它設置爲「只讀」,你總是可以改變它的內容,但不能改變指針的內容。 看看這個:
irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
from (irb):34
from /usr/local/bin/irb:11:in `<main>'
正如你看到的是可能刪除的散列@a一個鍵/值對,如添加新鍵,變化值,eccetera。但是你不能指向一個新的對象,因爲它是一個只讀實例變量。
我只希望他們記錄下來。 http://api.rubyonrails.org/?q=attr_reader – Chloe 2014-05-09 03:06:01
@Chloe你看錯了地方!這是一個Ruby方法,而不是* Rails *:http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-attr_reader – 2014-06-30 00:15:29
可能的重複[什麼是attr \ _accessor in Ruby ?](http://stackoverflow.com/questions/4370960/what-is-attr-accessor-in-ruby) – sschuberth 2014-12-11 16:53:18