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

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

Жанры

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

Все животные равны, но некоторые равнее других.

Джордж Оруэлл, «Скотный двор»

При написании своих классов желательно, чтобы семантика типичных операций была такой же, как у встроенных в Ruby классов. Например, если объекты класса можно упорядочивать, то имеет смысл реализовать метод

<=>
и подмешать модуль
Comparable
. Тогда к объектам вашего класса будут применимы все обычные операции сравнения.

Однако картина перестает быть такой однозначной, когда дело доходит до проверки объектов на равенство. В Ruby объекты реализуют пять разных методов

для этой операции. И в ваших классах придется реализовать хотя бы некоторые из них, поэтому рассмотрим этот вопрос подробнее.

Самым главным является метод

equal?
(унаследованный от класса
Object
); он возвращает
true
, если вызывающий объект и параметр имеют один и тот же идентификатор объекта. Это фундаментальный аспект семантики объектов, поэтому переопределять его не следует.

Самым распространенным способом проверки на равенство является старый добрый оператор

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

Следующим в шкале абстракции стоит метод

eql?
— тоже часть класса
Object
. (На самом деле метод
eql?
реализован в модуле
Kernel
, который подмешивается в
Object
.) Как и оператор
==
, этот метод сравнивает значения вызывающего объекта и аргумента, но несколько более строго. Например, разные числовые объекты при сравнении с помощью
==
приводятся к общему типу, но метод
eql?
никогда не считает объекты разных типов равными.

flag1 = (1 == 1.0) # true

flag2 = (1.eql?(1.0)) # false

Метод

eql?
существует по одной-единственной причине: для сравнения значений ключей хэширования. Если вы хотите переопределить стандартное поведение Ruby при использовании объектов в качестве ключей хэша, то переопределите методы
eql?
и
hash
.

Любой объект реализует еще два метода сравнения. Метод

===
применяется для сравнения проверяемого значения в предложении
case
с каждым селектором:
selector===target
. Хотя правило на первый взгляд кажется сложным, на практике оно делает предложения
case
в Ruby интуитивно очевидными. Например, можно выполнить ветвление по классу объекта:

case an_object

 when String

puts "Это строка."

 when Numeric

puts "Это число."

 else

puts "Это что-то совсем другое."

end

Эта конструкция работает, потому что в классе

Module
реализован метод
===
, проверяющий, принадлежит ли параметр тому же классу, что вызывающий объект (или одному из его предков). Поэтому, если
an_object
— это строка «cat», выражение
string === an_object
окажется истинным и будет выбрана первая ветвь в предложении
case
.

Наконец, в Ruby реализован оператор сопоставления с образцом

=~
.
Традиционно он применяется для сопоставления строки с регулярным выражением. Но если вы найдете ему применение в других классах, то можете переопределить.

У операторов

==
и
=~
есть противоположные формы:
!=
и
!~
соответственно. Внутри они реализованы путем обращения значения основной формы. Это означает, что если, например, вы реализовали метод
==
, то метод
!=
получаете задаром.

11.1.8. Управление доступом к методам

В Ruby объект определяется, прежде всего, своим интерфейсом: теми методами, которые он раскрывает внешнему миру. Но при написании класса часто возникает необходимость во вспомогательных методах, вызывать которые извне класса опасно. Тут-то и приходит на помощь метод

private
класса
Module
.

Использовать его можно двумя способами. Если в теле класса или модуля вы вызовете

private
без параметров, то все последующие методы будут закрытыми в данном классе или модуле. Если же вы передадите ему список имен методов (в виде символов), то эти и только эти методы станут закрытыми. В листинге 11.5 показаны оба варианта.

Листинг 11.5. Закрытые методы

class Bank

 def open_safe

# ...

 end

 def close_safe

# ...

 end

 private :open_safe, :close_safe

 def make_withdrawal(amount)

if access_allowed

open_safe

get_cash(amount)

close_safe

end

 end

 # Остальные методы закрытые.

private

 def get_cash

# ...

 end

 def access_allowed

# ...

 end

end

Поскольку методы из семейства

attr
просто определяют методы, метод
private
определяет и видимость атрибутов.

Реализация метода

private
может показаться странной, но на самом деле она весьма хитроумна. К закрытым методам нельзя обратиться, указав вызывающий объект; они вызываются только от имени неявно подразумеваемого объекта
self
. То есть вызвать закрытый метод из другого объекта не удастся: просто не существует способа указать объект, от имени которого данный метод вызывается. Заодно это означает, что закрытые методы доступны подклассам того класса, в котором определены, но опять же в рамках одного объекта.

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

Воронцов. Перезагрузка. Книга 4

Тарасов Ник
4. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 4

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Последний Герой. Том 5

Дамиров Рафаэль
5. Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 5

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

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

Барон Дубов 4

Карелин Сергей Витальевич
4. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 4

Воронцов. Перезагрузка. Книга 5

Тарасов Ник
5. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 5

Я еще царь. Книга XXX

Дрейк Сириус
30. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я еще царь. Книга XXX

Шайтан Иван 3

Тен Эдуард
3. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Шайтан Иван 3

Страж Кодекса. Книга V

Романов Илья Николаевич
5. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга V

Имя нам Легион. Том 13

Дорничев Дмитрий
13. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 13

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

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

Сапер. Том II

Вязовский Алексей
2. Сапер
Фантастика:
альтернативная история
4.25
рейтинг книги
Сапер. Том II

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Черный Маг Императора 15

Герда Александр
15. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Черный Маг Императора 15