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

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

Жанры

Программирование на языке 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

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

Поход

Валериев Игорь
4. Ермак
Фантастика:
боевая фантастика
альтернативная история
6.25
рейтинг книги
Поход

Книга гор (сборник)

Лукьяненко Сергей Васильевич
Фантастика:
социально-философская фантастика
героическая фантастика
6.12
рейтинг книги
Книга гор (сборник)

Полное собрание сочинений в одном томе

По Эдгар Аллан
Полное собрание в одном томе
Фантастика:
ужасы и мистика
детективная фантастика
мистика
8.40
рейтинг книги
Полное собрание сочинений в одном томе

Театральный роман (Сборник)

Булгаков Михаил Афанасьевич
Проза:
классическая проза
5.00
рейтинг книги
Театральный роман (Сборник)

Технология XSLT

Валиков Алексей Н.
Компьютеры и Интернет:
программирование
5.00
рейтинг книги
Технология XSLT

Эфемер

Прокофьев Роман Юрьевич
7. Стеллар
Фантастика:
боевая фантастика
рпг
7.23
рейтинг книги
Эфемер

Наследие Маозари

Панежин Евгений
1. Наследие Маозари
Фантастика:
рпг
попаданцы
аниме
5.80
рейтинг книги
Наследие Маозари

Том 6. Пьесы 1901-1906

Горький Максим
6. Собрание сочинений в тридцати томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 6. Пьесы 1901-1906

Эрбат. Пленники судьбы

Корнилова Веда
2. Эрбат
Фантастика:
фэнтези
6.25
рейтинг книги
Эрбат. Пленники судьбы

Имперец. Том 1 и Том 2

Романов Михаил Яковлевич
1. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 1 и Том 2

Кодекс Охотника XXVIII

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

Темный карнавал (сборник)

Брэдбери Рэй Дуглас
1. Сборники рассказов Рэя Брэдбери
Фантастика:
социально-философская фантастика
научная фантастика
ужасы и мистика
мистика
сказочная фантастика
7.71
рейтинг книги
Темный карнавал (сборник)

Геном хищника. Книга третья

Гарцевич Евгений Александрович
3. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга третья

Дважды одаренный. Том II

Тарс Элиан
2. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.25
рейтинг книги
Дважды одаренный. Том II