Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Есть и еще одна ситуация, когда желательно выполнять такие преобразования «за кулисами». Пользователь языка ожидает, что
FixnumFloatComplex+FixnumFloatFixnumcoerceКогда оператор
+coerceclass MyNumberSystem def +(other) if other.kind_of?(MyNumberSystem) result = some_calculation_between_self_and_other MyNumberSystem.new(result) else n1, n2 = other.coerce(self) n1 + n2 end endendМетод
coerceВ примере выше мы полагались на то, что класс аргумента умеет как-то выполнять приведение. Будь мы законопослушными гражданами, реализовали бы приведение и в собственном классе, чтобы он мог работать с числами других видов. Для этого нужно знать, с какими типами мы можем работать напрямую, и приводить объект к одному из этих типов, когда возникает необходимость. Если мы сами не знаем, как это сделать, следует спросить у родителя:
def coerce(other) if other.kind_of?(Float) return other, self.to_f elsif other.kind_of?(Integer) return other, self.to_i else super endendКонечно, чтобы этот пример работал, наш объект должен реализовывать методы
to_ito_fМетод
coerceclass String def coerce(n) if self['.'] [n, Float(self)] else [n, Integer(self)] end endendx = 1 + "23" # 24y = 23 * "1.23" # 29.29Впрочем, поступать так необязательно. Однако мы настоятельно рекомендуем реализовывать метод
coerce11.1.14. Классы, содержащие только данные (Struct)
Иногда нужно просто сгруппировать взаимосвязанные данные, не определяя никакие специфические методы обработки. Можно для этого создать класс:
class Address attr_accessor :street, :city, :state def initialize(street1, city, state) @street, @city, @state = street, city, state endendbooks = Address.new("411 Elm St", "Dallas", "TX")Такое решение годится, но каждый раз прибегать к нему утомительно; к тому же здесь слишком много повторов. Тут-то и приходит на помощь встроенный класс
Structattr_accessorStructAddress = Struct.new("Address", :street, :city, :state)books = Address.new("411 Elm St", "Dallas", "TX")Зачем передавать первым параметром конструктора имя создаваемой структуры и присваивать результат константе (в данном случае
AddressПри вызове
Struct.newStructStructStruct.new("Address", :street, :city, :state)books = Struct::Address.new("411 Elm St", "Dallas", "TX")Создав структурный шаблон, вы вызываете его метод new для создания новых экземпляров данной конкретной структуры. Необязательно присваивать значения всем атрибутам в конструкторе. Опущенные атрибуты получат значение
nilHashStructКстати, не рекомендуем создавать структуру с именем
TmsStruct::Tms11.1.15. Замораживание объектов
Иногда необходимо воспрепятствовать изменению объекта. Это позволяет сделать метод
freezeObject
