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

на главную - закладки

Жанры

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

Для этого нужно определить метод

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
появился в версии Ruby 1.8, чтобы упростить решение этой задачи. Он возвращает «чистый», еще не инициализированный объект класса.

class Person

 attr_accessor :name, :age, :phone

 def initialize(n,a,p)

@name, @age, @phone = n, a, p

 end

end

p1 = Person.new("John Smith",29,"555-1234")

p2 = Person.allocate

p p1.age # 29

p p2.age # nil

11.1.12. Модули

Для использования модулей в Ruby есть две основных причины. Первая — облегчить управление пространством имен; если поместить константы и методы в модули, то будет меньше конфликтов имен. Хранящийся таким образом метод (метод модуля) вызывается с указанием имени модуля, то есть без вызывающего объекта. Точно так же вызывается и метод класса. Увидев вызовы вида

File.ctime
или
FileTest.exist?
, мы не можем определить по контексту, что
File
— это класс, а
FileTest
— модуль.

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

Мы уже говорили о методах модуля, а как насчет методов экземпляра? Модуль — это не класс,

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

Но оказывается, модуль может иметь методы экземпляра. Они становятся частью класса, который включил модуль директивой

include
.

module MyMod

 def meth1

puts "Это метод 1."

 end

end

class MyClass

 include MyMod

 # ...

end

x = MyClass.new

x.meth1 # Это метод 1.

Здесь модуль

MyMod
подмешан к классу
MyClass
, а метод экземпляра
meth1
унаследован. Вы видели также, как директива
include
употребляется на верхнем уровне программы; в таком случае модуль подмешивается к классу
Object
.

А что происходит с методами модуля, если таковые определены? Если вы думаете, что они становятся методами класса, то ошибаетесь. Методы модуля не подмешиваются.

Но если такое поведение желательно, то его можно реализовать с помощью нехитрого трюка. Существует метод

append_features
, который можно переопределить. Он вызывается с параметром — «целевым» классом или модулем (в который включается данный модуль). Пример приведен в листинге 11.6.

Листинг 11.6. Включение модуля с переопределенным методом append_features

module MyMod

 def MyMod.append_features(someClass)

def someClass.modmeth

puts "Метод модуля (класса) "

end

super # Этот вызов обязателен!

 end

 def meth1

puts "Метод 1"

 end

end

class MyClass

 include MyMod

 def MyClass.classmeth

puts "Метод класса"

 end

 def meth2

puts "Метод 2"

 end

end

x = MyClass.new

# Выводится:

MyClass.classmeth # Метод класса

x.meth1 # Метод 1

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

Гримуар темного лорда VIII

Грехов Тимофей
8. Гримуар темного лорда
Фантастика:
боевая фантастика
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.25
рейтинг книги
Гримуар темного лорда VIII

Точка Бифуркации V

Смит Дейлор
5. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации V

Тихий Дон. Том 2

Шолохов Михаил Александрович
199. Библиотека всемирной литературы
Проза:
советская классическая проза
6.40
рейтинг книги
Тихий Дон. Том 2

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Сабрина

Делински Барбара
Любовные романы:
современные любовные романы
6.60
рейтинг книги
Сабрина

Своевольная красавица

Лоуренс Стефани
3. Кинстеры
Любовные романы:
исторические любовные романы
9.20
рейтинг книги
Своевольная красавица

Линия огня

Орехов Василий
9. S.T.A.L.K.E.R.
Фантастика:
боевая фантастика
8.74
рейтинг книги
Линия огня

Избранное

Герт Юрий Михайлович
Проза:
современная проза
5.00
рейтинг книги
Избранное

Предсказание

Катри Клинг
Фантастика:
фэнтези
5.00
рейтинг книги
Предсказание

Юрий Долгорукий (Сборник)

Загребельный Павел Архипович
Проза:
историческая проза
5.00
рейтинг книги
Юрий Долгорукий (Сборник)

Локки 2. Потомок бога

Решетов Евгений Валерьевич
2. Локки
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Локки 2. Потомок бога

Тайны Удольфского замка. Том 2

Рэдклиф Анна
Детективы:
триллеры
6.25
рейтинг книги
Тайны Удольфского замка. Том 2

Тот, кто знает. Книга вторая. Перекресток

Маринина Александра
5.00
рейтинг книги
Тот, кто знает. Книга вторая. Перекресток

Марш обреченных

Злобин Михаил
1. Хроники геноцида
Фантастика:
фэнтези
попаданцы
5.60
рейтинг книги
Марш обреченных