Пользовательские сеттеры
Часть раздела Объектно-ориентированное программирование путешествия по 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Выражение присваивания всегда возвращает значение в его правой части, а не то, что возвращает или сохраняет сеттер. Чтобы увидеть сохранённое значение, прочитайте атрибут ещё раз:
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