Attributen gebruiken met Ruby Code

Kijk eens objectgeoriënteerde code en het volgt min of meer hetzelfde patroon. Maak een object, roep enkele methoden voor dat object aan en open de kenmerken van dat object. Er is niet veel anders dat u met een object kunt doen, behalve het als een parameter doorgeven aan de methode van een ander object. Maar waar we ons hier zorgen over maken zijn attributen.

Attributen zijn als instantievariabelen u heeft toegang via de objectpuntnotatie. Bijvoorbeeld, person.name toegang zou hebben tot de naam van een persoon. Evenzo kunt u vaak toewijzen aan kenmerken zoals person.name = "Alice". Dit is een vergelijkbare functie als lidvariabelen (zoals in C ++), maar niet helemaal hetzelfde. Er is hier niets speciaals aan de hand, attributen worden in de meeste talen geïmplementeerd met behulp van "getters" en "setters", of methoden die de attributen ophalen en instellen uit instantievariabelen.

Ruby maakt geen onderscheid tussen kenmerkende getters en setters en normale methoden. Vanwege Ruby's flexibele methode die syntaxis aanroept, hoeft er geen onderscheid te worden gemaakt. Bijvoorbeeld,

instagram viewer
person.name en person.name () zijn hetzelfde, u belt de naam methode met nul parameters. De ene ziet eruit als een methodeaanroep en de andere ziet eruit als een attribuut, maar ze zijn eigenlijk allebei hetzelfde. Ze bellen allebei gewoon de naam methode. Evenzo kan elke naam van een methode die op een gelijkteken (=) eindigt, in een opdracht worden gebruikt. De verklaring person.name = "Alice" is eigenlijk hetzelfde als person.name = (alice), ook al zit er een spatie tussen de attribuutnaam en het isgelijkteken, het roept nog steeds gewoon de naam = methode.

U kunt attributen eenvoudig zelf implementeren. Door setter- en getter-methoden te definiëren, kunt u elk gewenst kenmerk implementeren. Hier is een voorbeeldcode die de naam attribuut voor een persoonsklasse. Het slaat de naam op in een @naam instantievariabele, maar de naam hoeft niet hetzelfde te zijn. Onthoud dat er niets bijzonders is aan deze methoden.

Een ding dat je meteen opvalt, is dat dit veel werk is. Het is veel typen om te zeggen dat je een attribuut met de naam wilt naam die toegang heeft tot de @naam instantievariabele. Gelukkig biedt Ruby enkele gemaksmethoden die deze methoden voor u zullen definiëren.

Er zijn drie methoden in de Module klasse die u kunt gebruiken in uw klasseverklaringen. Onthoud dat Ruby geen onderscheid maakt tussen runtime en "compile time", en elke code in klassedeclaraties kan niet alleen methoden definiëren, maar ook methoden aanroepen. Ik bel de attr_reader, attr_writer en attr_accessor methoden zullen op hun beurt de setters en getters definiëren die we zelf in de vorige sectie definieerden.

De attr_reader methode doet precies wat het klinkt zoals het zal doen. Er zijn een aantal symboolparameters nodig en voor elke parameter wordt een "getter" -methode gedefinieerd die de instantievariabele met dezelfde naam retourneert. Dus we kunnen onze vervangen naam methode in het vorige voorbeeld met attr_reader: naam.

Evenzo is de attr_writer methode definieert een "setter" -methode voor elk symbool dat eraan wordt doorgegeven. Merk op dat het isgelijkteken geen deel mag uitmaken van het symbool, alleen de attribuutnaam. We kunnen de naam = methode uit het vorige voorbeeld met een oproep naar attr_writier: naam.

En, zoals verwacht, attr_accessor doet het werk van beide attr_writer en attr_reader. Als u zowel een setter als een getter nodig heeft voor een kenmerk, is het gebruikelijk om de twee methoden niet afzonderlijk aan te roepen en in plaats daarvan aan te roepen attr_accessor. We kunnen vervangen beide de naam en naam = methoden uit het vorige voorbeeld met een enkele aanroep attr_accessor: naam.

Waarom moet u setters handmatig definiëren? Waarom niet de attr_ * methoden elke keer? Omdat ze inkapseling doorbreken. Inkapseling is het principe dat stelt dat geen enkele externe entiteit onbeperkte toegang mag hebben tot de interne staat van uw voorwerpen. Alles moet toegankelijk zijn via een interface die voorkomt dat de gebruiker de interne staat van het object beschadigt. Met behulp van de bovenstaande methoden hebben we een groot gat in onze inkapselingsmuur geslagen en hebben we absoluut alles toegestaan ​​voor een naam, zelfs duidelijk ongeldige namen.

Een ding dat je vaak zult zien, is dat attr_reader zal worden gebruikt om snel een getter te definiëren, maar een aangepaste setter zal worden gedefinieerd omdat de interne status van het object vaak lezen rechtstreeks vanuit de interne staat. De setter wordt vervolgens handmatig gedefinieerd en controleert of de ingestelde waarde logisch is. Of, misschien vaker, wordt helemaal geen setter gedefinieerd. De andere methoden in de class-functie zetten de instantievariabele op een andere manier achter de getter.

We kunnen nu een toevoegen leeftijd en goed implementeren naam attribuut. De leeftijd attribuut kan worden ingesteld in de constructormethode, gelezen met behulp van de leeftijd getter maar alleen gemanipuleerd met de verjaardag hebben methode, die de leeftijd zal verhogen. De naam attribuut heeft een normale getter, maar de setter zorgt ervoor dat de naam een ​​hoofdletter heeft en de vorm heeft van Voornaam Achternaam.