Книга: Программирование на языке Ruby

11.1.10. Метод initialize_copy

11.1.10. Метод initialize_copy

При копировании объекта методом dup или clone конструктор не вызывается. Копируется вся информация о состоянии.

Но что делать, если вам такое поведение не нужно? Рассмотрим пример:

class Document
 attr_accessor :title, :text
 attr_reader :timestamp
 def initialize(title, text)
  @title, @text = title, text
  @timestamp = Time.now
 end
end
doc1 = Document.new("Random Stuff",File.read("somefile"))
sleep 300 # Немного подождем...
doc2 = doc1.clone
doc1.timestamp == doc2.timestamp # true
# Оп... временные штампы одинаковы!

При создании объекта Document с ним ассоциируется временной штамп. При копировании объекта копируется и его временной штамп. А как быть, если мы хотим запомнить время, когда было выполнено копирование?

Для этого нужно определить метод initialize_copy. Он вызывается как раз при копировании объекта. Этот метод аналогичен initialize и позволяет полностью контролировать состояние объекта.

class Document # Определяем новый метод в классе.
 def initialize_copy(other)
  @timestamp = Time.now
 end
end
doc3 = Document.new("More Stuff", File.read("otherfile"))
sleep 300                        # Немного подождем...
doc4 = doc3.clone
doc3.timestamp == doc4.timestamp # false
# Теперь временные штампы правильны.

Отметим, что метод initialize_copy вызывается после того, как вся информация скопирована. Поэтому мы и опустили строку:

@title, @text = other.title, other.text

Кстати, если метод initialize_copy пуст, то поведение будет такое же, как если бы он не был определен вовсе.

Оглавление книги


Генерация: 1.022. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз