Дисклеймер

Інформація на сайті tseivo.com є суб'єктивною та відображає особисті погляди та досвід авторів та авторок блогів.

Використовуйте цей ресурс як одне з декількох джерел інформації під час своїх досліджень та прийняття рішень. Завжди застосовуйте критичне мислення. Людина сама несе відповідальність за свої рішення та дії.

Що таке attr_accessor, attr_reader та attr_writer у Ruby? Для чого вони потрібні?

У Ruby attr_accessor є макросом (або методом) для автоматичного створення геттера (методу доступу до значення) та сеттера (методу встановлення значення) для інстансних змінних (instance variables) в класі.
Наприклад:
class Cat
end

cat = Cat.new
cat.name # => no method error
Ми не маємо методу name у класі Cat. Вочевидь ми отримуємо no method error.
Спробуємо додати геттер:
class Cat
  def name
    @name # повертає змінну екземпляра @name
  end
end

cat = Cat.new
cat.name # => nil
Здається, що щось пішло не так. Але все правильно. Геттер cat.name повертає nil. Вже немає помилки 'no method error', тобто метод існує, та повертає змінну @name екземпляра Cat. Але ця змінна пуста. nil - це очікуємий результат.
У Ruby геттер є методом, який дозволяє отримати значення інстансної змінної (instance variable) в класі. Геттери називаються так, оскільки вони дозволяють "отримувати" (get) значення змінної.
У Ruby геттери зазвичай використовуються для забезпечення доступу до значень змінних ззовні класу, оскільки змінні зазвичай є приватними (private) і недоступними безпосередньо. Геттери дозволяють забезпечити контрольований доступ до цих значень.
Cпроба використати сеттер видає помилку no method error:
cat.name = 'Ruby'# => no method error
Це теж очікуємий результат. Ми не маємо сеттер методу для name.
У Ruby сеттер є методом, який дозволяє встановити значення інстансної змінної (instance variable) в класі. Сеттери називаються так, оскільки вони дозволяють "встановлювати" (set) (або змінювати існуючі) значення змінної.
У Ruby сеттери використовуються для контрольованого змінювання значень змінних ззовні класу. 
class Cat
  def name
    @name # повертає змінну екземпляра @name
  end

  def name=(str)
    @name = str
  end
end
Cтворимо екземпляр Cat та викличемо метод name (геттер):
cat = Cat.new
cat.name # => nil
Тут все правильно. Наш екземпляр наразі пустий. Треба передати значення за допомогою нашого нового методу (сеттер).
cat.name = 'Ruby'
Ми не бачимо ніякої помилки. Тож спробуємо за допомого гетер методу витягнути значення:
cat.name # => Ruby
Все працює. Але уявіть, що у вашого класу не тільки name, а десятки різних атрібутів (вік, колір та інше). Кожного разу писати геттер та сеттер методи не дуже зручно.
Тож в Ruby є такі собі скорочення (attr_reader та attr_writer):
class Cat
  attr_reader :name
  attr_writer :name
end
 
:name - назва атрібуту, для якого створюється метод.
attr_reader - це скорочення для геттер методу:
def name
  @name # повертає змінну екземпляра @name
end
attr_writer - це скорочення для сеттер методу:
def name=(str)
  @name = str
end
Але коли нам потрібні обидва методи - сеттер та геттер, attr_reader та attr_writer треба дублювати їх для кожного атрібуту:
class Cat
  attr_reader :name
  attr_writer :name
  attr_reader :color
  attr_writer :color
end
Це локанічніше ніж писати методи повністю, але Ruby дає змогу скоротити і цей код. тут нам потрібен attr_accessor.
class Cat
  attr_accessor :name
  attr_accessor :color
end
Рівноцінно запису:
class Cat
  attr_reader :name
  attr_writer :name
  attr_reader :color
  attr_writer :color
end
Використання attr_accessor, attr_reader та attr_writer спрощує створення методів доступу до змінних у класах, і це особливо зручно, коли вам потрібно лише просто отримати або встановити значення змінної, без додаткової логіки.
Ruby дозволяє скоротити вже те, що здається ти вже скоротив. Ось варіант скороченного запису атрибутів через кому:
attr_reader :name, :color

🙌 Підтримати блог @memecode

Ви можете поширити цей допис у соцмережах, чим допоможете платформі цейво розвиватись (* ^ ω ^)

📝 Більше публікацій: