Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

11.1.14. Классы, содержащие только данные (Struct)

Иногда нужно просто сгруппировать взаимосвязанные данные, не определяя никакие специфические методы обработки. Можно для этого создать класс:

class Address

 attr_accessor :street, :city, :state

 def initialize(street1, city, state)

@street, @city, @state = street, city, state

 end

end

books = Address.new("411 Elm St", "Dallas", "TX")

Такое решение годится, но каждый раз прибегать к нему утомительно; к тому же здесь слишком много повторов. Тут-то и приходит на помощь встроенный класс

Struct
. Если вспомогательные методы типа
attr_accessor
определяют методы доступа к атрибутам, то
Struct
определяет целый класс, который может содержать только атрибуты. Такие классы называются структурными шаблонами.

Address = Struct.new("Address", :street, :city, :state)

books = Address.new("411 Elm St", "Dallas", "TX")

Зачем передавать первым параметром конструктора имя создаваемой структуры и присваивать результат константе (в данном случае

Address
)?

При вызове

Struct.new
для создания нового структурного шаблона на самом деле создается новый класс внутри самого класса
Struct
. Этому классу присваивается имя, переданное первым параметром, а остальные параметры становятся именами его атрибутов. При желании к вновь созданному классу можно было бы получить доступ, указав пространство имен
Struct
:

Struct.new("Address", :street, :city, :state)

books = Struct::Address.new("411 Elm St", "Dallas", "TX")

Создав структурный шаблон, вы вызываете его метод new для создания новых экземпляров данной конкретной структуры. Необязательно присваивать значения всем атрибутам в конструкторе. Опущенные атрибуты получат значение

nil
. После того как структура создана, к ее атрибутам можно обращаться с помощью обычного синтаксиса или указывая их имена в скобках в качестве индекса, как будто структура - это объект класса
Hash
. Более подробную информацию о классе
Struct
можно найти в любом справочном руководстве (например, на сайте ruby.doc.org).

Кстати, не рекомендуем создавать структуру с именем

Tms
, так как уже есть предопределенный класс
Struct::Tms
.

11.1.15. Замораживание объектов

Иногда необходимо воспрепятствовать изменению объекта. Это позволяет сделать метод

freeze
(определенный в классе
Object
). По существу, он превращает объект в константу.

Попытка модифицировать замороженный объект приводит к исключению

TypeError
. В листинге 11.8 приведено два примера.

Листинг 11.8. Замораживание объекта

str = "Это тест. "

str.freeze

begin

 str << " He волнуйтесь." # Попытка модифицировать.

rescue => err

 puts "#{err.class} #{err}"

end

arr = [1, 2, 3]

arr.freeze

begin

 arr << 4 # Попытка модифицировать.

rescue => err

 puts "#{err.class} #{err}"

end

# Выводится:

# TypeError: can't modify frozen string

# TypeError: can't modify frozen array

Однако имейте в виду, что метод

freeze
применяется к ссылке на объект, а не к переменной! Это означает, что любая операция, приводящая к созданию нового объекта, завершится успешно. Иногда это противоречит интуиции. В примере ниже мы ожидаем, что операция
+=
не выполнится, но все работает нормально. Дело в том, что присваивание — не вызов метода. Эта операция воздействует на переменные, а не на объекты, поэтому новый объект создается беспрепятственно. Старый объект по-прежнему заморожен, но переменная ссылается уже не на него.

str = "counter-"

str.freeze

str += "intuitive" # "counter-intuitive"

arr = [8, 6, 7]

arr.freeze

arr += [5, 3, 0, 9] # [8, 6, 7, 5, 3, 0, 9]

Почему так происходит? Предложение

a += x
семантически эквивалентно
a = a + x
. При вычислении выражения
a + x
создается новый объект, который затем присваивается переменной
a
! Все составные операторы присваивания работают подобным образом, равно как и другие методы. Всегда задавайте себе вопрос: «Что я делаю — создаю новый объект или модифицирую существующий?» И тогда поведение
freeze
не станет для вас сюрпризом.

  • Читать дальше
  • 1
  • ...
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: