Использование атрибутов с кодом Ruby

Посмотри на любой объектно-ориентированный код и все это более или менее следует той же схеме. Создайте объект, вызовите некоторые методы для этого объекта и получите доступ к атрибутам этого объекта. Вы не можете ничего сделать с объектом, кроме как передать его в качестве параметра методу другого объекта. Но здесь нас интересуют атрибуты.

Атрибуты похожи переменные экземпляра Вы можете получить доступ через обозначение точки объекта. Например, person.name будет иметь доступ к имени человека. Точно так же вы можете часто назначать атрибуты, такие как person.name = "Алиса". Это похоже на переменные-члены (такие как в C ++), но не совсем то же самое. Здесь ничего особенного не происходит, атрибуты реализованы в большинстве языков с использованием «получателей» и «установщиков» или методов, которые извлекают и устанавливают атрибуты из переменных экземпляра.

Ruby не делает различий между методами получения и установки атрибутов и обычными методами. Из-за гибкого синтаксиса вызова методов в Ruby никаких различий не требуется. Например,

instagram viewer
person.name и person.name () одно и то же, вы называете имя метод с нулевыми параметрами. Один выглядит как вызов метода, а другой - как атрибут, но на самом деле это одно и то же. Они оба просто звонят имя метод. Точно так же любое имя метода, заканчивающееся знаком равенства (=), может использоваться в присваивании. Заявление person.name = "Алиса" действительно то же самое, что person.name = (Алисе)даже если между именем атрибута и знаком равенства есть пробел, он все равно просто вызывает имя = метод.

Вы можете легко реализовать атрибуты самостоятельно. Определив методы setter и getter, вы можете реализовать любой атрибут, который пожелаете. Вот пример кода, реализующего имя атрибут для человека класса. Он хранит имя в @имя переменная экземпляра, но имя не обязательно должно совпадать. Помните, в этих методах нет ничего особенного.

Одна вещь, которую вы сразу заметите, это то, что это много работы. Это много печатать, просто чтобы сказать, что вы хотите атрибут с именем имя который получает доступ к @имя переменная экземпляра. К счастью, Ruby предоставляет несколько удобных методов, которые определят эти методы для вас.

Есть три метода в модуль класс, который вы можете использовать внутри ваших объявлений класса. Помните, что Ruby не делает различий между временем выполнения и временем компиляции, и любой код внутри объявлений класса может не только определять методы, но и вызывать методы. Вызов attr_reader, attr_writer и attr_accessor методы, в свою очередь, определяют сеттеры и геттеры, которые мы определяли сами в предыдущем разделе.

attr_reader Метод так же, как и звучит. Он принимает любое количество параметров символа и для каждого параметра определяет метод «getter», который возвращает переменную экземпляра с тем же именем. Таким образом, мы можем заменить наш имя Метод в предыдущем примере с attr_reader: имя.

Точно так же attr_writer Метод определяет метод «сеттер» для каждого передаваемого ему символа. Обратите внимание, что знак равенства не обязательно должен быть частью символа, а только именем атрибута. Мы можем заменить имя = метод из предыдущего примера с вызовом attr_writier: имя.

И, как и ожидалось, attr_accessor выполняет работу обоих attr_writer и attr_reader. Если для атрибута требуются как установщик, так и получатель, обычной практикой является не вызывать два метода по отдельности, а вместо этого вызывать attr_accessor. Мы могли бы заменить и то и другое имя и имя = методы из предыдущего примера с одним вызовом attr_accessor: имя.

Почему вы должны определять сеттеры вручную? Почему бы не использовать attr_ * методы каждый раз? Потому что они нарушают инкапсуляцию. Инкапсуляция - это принцип, который гласит, что ни один внешний объект не должен иметь неограниченный доступ к внутреннему состоянию вашего объекты. Все должно быть доступно с помощью интерфейса, который предотвращает повреждение пользователем внутреннего состояния объекта. Используя описанные выше методы, мы пробили большую дыру в нашей стене инкапсуляции и позволили установить абсолютно любое имя, даже явно недопустимые имена.

Вы часто видите, что attr_reader будет использоваться для быстрого определения получателя, но будет определен пользовательский установщик, так как внутреннее состояние объекта часто хочет быть читать прямо из внутреннего состояния. Затем сеттер определяется вручную и выполняет проверки, чтобы убедиться, что устанавливаемое значение имеет смысл. Или, возможно, чаще всего, никакой установщик не определен вообще. Другие методы в функции класса устанавливают переменную экземпляра за получателем другим способом.

Теперь мы можем добавить возраст и правильно реализовать имя атрибут. возраст атрибут может быть установлен в методе конструктора, читать с помощью возраст геттер, но манипулировать только с have_birthday метод, который увеличит возраст. имя Атрибут имеет нормальный метод получения, но он устанавливает, что имя написано с большой буквы и имеет вид Имя Фамилия.