Вижте всяка обектно ориентиран код и всичко това повече или по-малко следва същия модел. Създайте обект, извикайте някои методи за този обект и достъп до атрибутите на този обект. Няма много друго, което можете да направите с обект, освен да го предадете като параметър на метода на друг обект. Но това, което ни интересува тук, са атрибутите.
Атрибутите са като примерни променливи можете да получите достъп чрез нотация на обектната точка. Например, person.name ще има достъп до името на човек. По подобен начин често можете да присвоявате атрибути като person.name = "Алиса". Това е подобна функция на променливите член (като например в C ++), но не е съвсем същото. Тук няма нищо особено, атрибутите се реализират на повечето езици, използвайки "getters" и "setters" или методи, които извличат и задават атрибутите от променливите на инстанцията.
Ruby не прави разлика между получателите на атрибути и setters и нормалните методи. Поради гъвкавия метод на Ruby, призоваващ синтаксис, не трябва да се прави разлика. Например,
person.name и person.name () са едно и също нещо, вие се обаждате на име метод с нулеви параметри. Единият изглежда като призив на метод, а другият прилича на атрибут, но всъщност и двете са едно и също нещо. И двамата просто се обаждат на име метод. По същия начин, всяко име на метод, което завършва със знак равен (=), може да се използва в задание. Изявлението person.name = "Алиса" наистина е същото person.name = (Alice), въпреки че има интервал между името на атрибута и знака равен, той все още просто се обажда на име = метод.Можете лесно да внедрите атрибутите сами. Чрез дефиниране на методите на setter и getter можете да внедрите всеки атрибут, който желаете. Ето някои примерен код за изпълнение на име атрибут за клас човек. Той съхранява името в a @name примерна променлива, но името не трябва да е същото. Не забравяйте, че няма нищо особено в тези методи.
Едно нещо, което ще забележите веднага, е, че това е много работа. Много е да пишете, само за да кажете, че искате атрибут с име име който има достъп до @name примерна променлива. За щастие, Ruby предоставя някои удобни методи, които ще определят тези методи за вас.
Има три метода в модул клас, който можете да използвате вътре в декларациите си за клас. Не забравяйте, че Ruby не прави разлика между време на изпълнение и "време за компилиране", а всеки код вътре в декларациите от клас може не само да дефинира методите, но и методите на повикване. Обаждане на attr_reader, attr_writer и attr_accessor методите от своя страна ще дефинират сетерите и гетерите, които сами дефинирахме в предишния раздел.
Най- attr_reader метод просто харесва това, което звучи, че ще направи. Той отнема произволен брой параметри на символа и за всеки параметър определя метод "getter", който връща променливата на екземпляра със същото име. Така че, можем да заменим нашите име метод в предишния пример с attr_reader: име.
По същия начин attr_writer метод определя метод "setter" за всеки предаван към него символ. Обърнете внимание, че знакът равен не трябва да бъде част от символа, а само името на атрибута. Можем да заменим име = метод от предишния пример с повикване до attr_writier: име.
И, както се очаква, attr_accessor върши ли работата и на двамата attr_writer и attr_reader. Ако се нуждаете както от setter, така и от getter за атрибут, обичайна практика е да не извиквате двата метода отделно, а вместо това да се обадите attr_accessor. Можем да заменим и двете на име и име = методи от предишния пример с едно повикване до attr_accessor: име.
Защо трябва да дефинирате сетери ръчно? Защо да не използвате attr_ * методи всеки път? Защото нарушават капсулацията. Капсулирането е главното, според което никое външно образувание не трябва да има неограничен достъп до вътрешното състояние на вашето обекти. Достъпа до всичко трябва да се използва с помощта на интерфейс, който не позволява на потребителя да повреди вътрешното състояние на обекта. Използвайки горните методи, ние пробихме голяма дупка в стената си за капсулиране и позволихме да се зададе абсолютно всичко за име, дори очевидно невалидни имена.
Едно нещо, което често ще видите, е това attr_reader ще се използва за бързо определяне на getter, но ще бъде дефиниран персонализиран сетер, тъй като вътрешното състояние на обекта често иска да бъде Прочети директно от вътрешното състояние. След това сетерът се дефинира ръчно и прави проверки, за да гарантира, че зададената стойност има смисъл. Или, може би по-често, изобщо не е дефиниран сетер. Другите методи във функцията class задават променливата инстанция зад getter по някакъв друг начин.
Вече можем да добавим и възраст и правилно прилагайте a име атрибут. Най- възраст атрибутът може да бъде зададен в метода на конструктора, като се чете с помощта на възраст getter, но само манипулиран с помощта на have_birthday метод, който ще увеличи възрастта. Най- име атрибутът има нормален гетер, но setter гарантира, че името е с главни букви и е под формата на Име, фамилия.