Чтение онлайн

на главную

Жанры

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

Модификатор доступа

protected
налагает меньше ограничений. Защищенные методы доступны только экземплярам того класса, в котором определены, и его подклассов. Для защищенного метода разрешается указывать вызывающий объект, так что к ним можно обращаться из других объектов (при условии, что вызывающий и вызываемый объекты принадлежат одному классу). Обычно защищенные методы применяются для определения методов доступа, чтобы два объекта одного типа могли взаимодействовать. В следующем примере объекты класс
Person
можно сравнивать по возрасту, но сам возраст недоступен вне класса
Person
:

class Person

 def initialize(name, age)

@name, @age = name, age

 end

 def <=>(other)

age <=> other.age

 end

 attr_reader :name, :age

 protected :age

end

p1 = Person.new("fred", 31)

p2 = Person.new("agnes", 43)

compare = (p1 <=> p2) # -1

x = p1.age # Ошибка!

Чтобы завершить картину, модификатор

public
делает метод открытым. Неудивительно!..

И последнее: методы, определенные вне любого класса и модуля (то есть на верхнем уровне программы), по умолчанию закрыты. Поскольку они определены в классе

Object
, то видимы глобально, но обращаться к ним с указанием вызывающего объекта нельзя.

11.1.9. Копирование объектов

Встроенные методы

Object#clone
и
#dup
порождают копию вызывающего объекта. Различаются они объемом копируемого контекста. Метод
#dup
копирует только само содержимое объекта, тогда как
clone
сохраняет и такие вещи, как синглетные классы, ассоциированные с объектом.

s1 = "cat"

def s1.upcase

 "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
во все встроенные классы Ruby, которыми вы пользуетесь.

Но есть и более быстрый способ с использованием модуля

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
с ним ассоциируется временной штамп. При копировании объекта копируется и его временной штамп. А как быть, если мы хотим запомнить время, когда было выполнено копирование?

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

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI

Александр Агренев. Трилогия

Кулаков Алексей Иванович
Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Александр Агренев. Трилогия

Телохранитель Генсека. Том 4

Алмазный Петр
4. Медведев
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Телохранитель Генсека. Том 4

Звездная Кровь. Изгой V

Елисеев Алексей Станиславович
5. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
фантастика: прочее
5.00
рейтинг книги
Звездная Кровь. Изгой V

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

Мастер 10

Чащин Валерий
10. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 10

Сокрушитель

Поселягин Владимир Геннадьевич
3. Уникум
Фантастика:
боевая фантастика
5.60
рейтинг книги
Сокрушитель

Адвокат Империи 3

Карелин Сергей Витальевич
3. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 3

Московское золото и нежная попа комсомолки. Часть Четвертая

Хренов Алексей
4. Летчик Леха
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Московское золото и нежная попа комсомолки. Часть Четвертая

Студиозус

Шмаков Алексей Семенович
3. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус

Кодекс Охотника. Книга XVII

Винокуров Юрий
17. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVII

Сирийский рубеж

Дорин Михаил
5. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж

Я - злодейка в дораме. Сезон второй

Вострова Екатерина
2. Выжить в дораме
Фантастика:
уся
фэнтези
сянься
попаданцы
5.00
рейтинг книги
Я - злодейка в дораме. Сезон второй