Пользовательские сеттеры
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 8 из 57.
Сеттер — это метод, имя которого заканчивается на =. Написав его самостоятельно вместо использования attr_writer, вы сможете обработать значение перед его сохранением:
class Person
attr_reader :name
def name=(value)
@name = value.strip.capitalize
end
end
ada = Person.new
ada.name = " aDA "
puts "[#{ada.name}]"Результат:
[Ada]Сеттер также может отклонить значение, вызвав ошибку. Переменной экземпляра присваивается значение только тогда, когда значение проходит проверку, поэтому объект сохраняет своё прежнее состояние:
class Product
attr_reader :price
def initialize(price)
@price = price
end
def price=(value)
raise ArgumentError, "price must be positive, got #{value}" if value <= 0
@price = value
end
end
item = Product.new(10)
begin
item.price = -5
rescue ArgumentError => e
puts e.message
end
puts item.priceВывод:
price must be positive, got -5
10Выражение присваивания всегда возвращает значение в правой части, а не то, что возвращает или сохраняет setter. Снова прочитайте атрибут, чтобы увидеть сохранённое значение:
class Thermometer
attr_reader :celsius
def celsius=(value)
@celsius = value.round
end
end
t = Thermometer.new
result = (t.celsius = 21.7)
puts result
puts t.celsiusВывод:
21.7
22Средство чтения и пользовательский сеттер вместе предоставляют атрибут, который внешний код может читать и изменять, но только до допустимых значений. Оставьте проверку только в сеттере, чтобы каждое изменение проходило через одно и то же правило:
class Volume
attr_reader :level
def level=(value)
raise ArgumentError, "level must be 0-10" unless (0..10).cover?(value)
@level = value
end
endЗадание
ЛегкоЗавершите класс Person. Его сеттер name= удаляет пробелы вокруг значения и делает каждое слово начинающимся с заглавной буквы ( ada lovelace превращается в Ada Lovelace). Его сеттер age= вызывает ArgumentError с сообщением invalid age: 200, когда возраст находится за пределами диапазона от 0 до 150, а в остальных случаях сохраняет его. Оба значения можно прочитать.
Новый экземпляр Person создаётся с именем Unknown и возрастом 0. Предоставленный код считывает команды name text или age n, применяет их через сеттеры и после каждой команды выводит человека в виде Ada Lovelace (36) либо выводит сообщение об ошибке, когда сеттер отклоняет значение.
Ваш код должен находиться в person.rb. Файл main.rb содержит предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
require_relative 'person'
# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
input << line.chomp
end
person = Person.new
input.each do |line|
command, value = line.split(" ", 2)
begin
command == "name" ? person.name = value : person.age = value.to_i
puts "#{person.name} (#{person.age})"
rescue ArgumentError => e
puts e.message
end
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовПеременные экземпляраМетоды и selfto_s и inspectПовторение — читательский билет4Инкапсуляция
Приватные методыЗащищённые методыПриватные сеттерыЗащита состоянияПовторение — торговый автомат7Полиморфизм и утиная типизация
ПолиморфизмУтиная типизацияАбстрактные методыcase и классыПовторение — способы оплаты10Шаблоны проектирования, часть 2
Делегирование с помощью ForwardableШаблон декоратораШаблон строителяШаблон состояния2Аксессоры и self
Чтение и записьПользовательские сеттерыself в методахИдентичность и равенствоПовторение — список контактов5Наследование
ПодклассыПереопределение методовВызов superis_a? и предкиПовторение — расчёт зарплаты сотрудников8Специальные методы
Равенство и хешированиеМетоды операторовИндексация и добавлениеПользовательские коллекцииПовторение — дроби11Проект: Управление библиотекой
Книги и читателиВыдача книг3Методы и переменные классов
Методы классовПеременные экземпляра классаКонстантыФабричные методыПовторение — коды купонов6Модули и примеси
Модули и includeРасширение объектовМодуль ComparableМодуль EnumerableПовторение — спортивная лига9Паттерны проектирования. Часть 1
Паттерн «Одиночка»Фабричный паттернПаттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор Ruby