Waarom ruby’s att_Accessor, etteringReader en attrawriter gebruiken?

Ruby heeft deze handige en handige manier om variabelen te delen met behulp van toetsen als

attr_accessor :var
attr_reader :var
attr_writer :var

Waarom zou ik attr_readerof attr_writerals ik eenvoudig attr_accessorkan gebruiken? Is er iets zoals prestaties (wat ik betwijfel)? Ik denk dat er een reden is, anders zouden ze dergelijke sleutels niet hebben gemaakt.


Antwoord 1, Autoriteit 100%

U kunt de verschillende accessors gebruiken om uw intentie te communiceren voor iemand die uw code leest en het gemakkelijker maken om klassen te schrijven die correct werken, ongeacht hoe hun openbare API wordt genoemd.

class Person
  attr_accessor :age
  ...
end

Hier kan ik zien dat ik allebei de leeftijd kan lezen en schrijven.

class Person
  attr_reader :age
  ...
end

Hier kan ik zien dat ik alleen de leeftijd kan lezen. Stel je voor dat het wordt ingesteld door de constructeur van deze klasse en daarna blijft constant. Als er sprake was van een mutator (schrijver) voor de leeftijd en de klasse werden geschreven, ervan uitgaande van die leeftijd, eenmaal ingesteld, verandert dan niet, dan kan een bug het gevolg zijn van code die die mutator oproept.

Maar wat gebeurt er achter de schermen?

Als u schrijft:

attr_writer :age

die wordt vertaald in:

def age=(value)
  @age = value
end

Als u schrijft:

attr_reader :age

Dat wordt vertaald in:

def age
  @age
end

Als je schrijft:

attr_accessor :age

Dat wordt vertaald in:

def age=(value)
  @age = value
end
def age
  @age
end

Dat wetende, hier is een andere manier om erover na te denken: als je de attr_… helpers niet had, en de accessors zelf moest schrijven, zou je dan meer accessors schrijven dan je klas nodig had? Als leeftijd bijvoorbeeld alleen gelezen hoeft te worden, zou u dan ook een methode schrijven waarmee het kan worden geschreven?


Antwoord 2, autoriteit 3%

Alle antwoorden hierboven zijn correct; attr_readeren attr_writerzijn handiger om te schrijven dan het handmatig typen van de methoden waarvoor ze een afkorting zijn. Afgezien daarvan bieden ze veel betere prestaties dan het zelf schrijven van de methodedefinitie. Zie dia 152 voor meer informatie vanaf dit gesprek(PDF) door Aaron Patterson.


Antwoord 3, autoriteit 2%

Het is belangrijk om te begrijpen dat accessors de toegang tot variabelen beperken, maar niet tot hun inhoud. In ruby is, net als in sommige andere OO-talen, elke variabele een verwijzing naar een instantie. Dus als je bijvoorbeeld een attribuut voor een hash hebt en je zet het op “alleen lezen”, dan kun je altijd de inhoud ervan wijzigen, maar niet de inhoud van de aanwijzer.
Kijk hier eens naar:

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>'

Zoals u kunt zien is mogelijk een sleutel / waardepaar uit de HASH @A verwijderen, zoals nieuwe toetsen toevoegen, waarden wijzigen, Eccetera. Maar u kunt niet wijzen op een nieuw object, omdat een alleen-lezen-variabele is.


Antwoord 4, Autoriteit 2%

Niet alle attributen van een object zijn bedoeld om direct van buiten de klas te worden ingesteld. Het hebben van schrijvers voor al uw exemplaarvariabelen is over het algemeen een teken van zwakke inkapseling en een waarschuwing die u teveel koppeling tussen uw lessen introduceert.

Als een praktisch voorbeeld: ik heb een ontwerpprogramma geschreven waar u items in containers plaatst. Het artikel had attr_reader :container, maar het heeft niet logisch om een ​​schrijver aan te bieden, omdat de enige keer dat de container van het item zou moeten veranderen, is wanneer het in een nieuwe wordt geplaatst, wat ook positionering-informatie vereist.


Antwoord 5, Autoriteit 2%

U wilt niet altijd dat uw instantievariabelen volledig toegankelijk zijn van buiten de klas. Er zijn tal van gevallen waarin het toestaan ​​van leestoegang tot een exemplaarvariabele logisch is, maar het schrijven daaraan niet (bijvoorbeeld een model dat gegevens van een alleen-lezen bron opneemt). Er zijn gevallen waarin je het tegenovergestelde wilt, maar ik kan niet bedenken dat dat niet van de bovenkant van mijn hoofd is gekunsteld.

Other episodes