Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
"CaT"
end
s1_dup = s1.dup
s1_clone = s1.clone
s1 #=> "cat"
s1_dup.upcase #=> "CAT" (синглетный метод не копируется)
s1_clone.upcase #=> "СаТ" (используется синглетный метод)
И
dup
clone
arr2
arr1
arr2[2]
arr1
String
arr2
arr1
arr1 = [ 1, "flipper", 3 ]
arr2 = arr1.dup
arr2[2] = 99
arr2[1][2] = 'a'
arr1 # [1, "flapper", 3]
arr2 # [1, "flapper", 99]
Иногда необходимо глубокое копирование, при котором копируется все дерево объектов с корнем в исходном объекте. В этом случае между оригиналом и копией гарантированно не будет никакой интерференции. Ruby не предоставляет встроенного метода для глубокого копирования, но есть приемы, позволяющие достичь желаемого результата.
Самый «чистый» способ — потребовать, чтобы классы реализовывали метод
deep_copy
deep_copy
deep_copy
Но есть и более быстрый способ с использованием модуля
Marshal
arr1 = [ 1, "flipper", 3 ]
arr2 = Marshal.load(Marshal.dump(arr1))
arr2[2] = 99
arr2[1][2] = 'a'
arr1 # [1, "flipper", 3]
arr2 # [1, "flapper", 99]
Обратите внимание, что изменение строки через
arr2
arr1
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
11.1.11. Метод allocate
Редко, но бывает, что нужно создать объект, не вызывая его конструктор (в обход метода
initialize
new
initialize
Метод
allocate