Книга: Программирование на языке Ruby
1.4.2. Отражение
1.4.2. Отражение
В языках Smalltalk, LISP и Java реализована (с разной степенью полноты) идея рефлексивного программирования — активная среда может опрашивать структуру объектов и расширять либо модифицировать их во время выполнения.
В языке Ruby имеется развитая поддержка отражения, но все же он не заходит так далеко, как Smalltalk, где даже управляющие конструкции являются объектами. В Ruby управляющие конструкции и блоки не представляют собой объекты. (Объект Proc
можно использовать для того, чтобы представить блок в виде объекта, но управляющие конструкции объектами не бывают никогда.)
Для определения того, используется ли идентификатор с данным именем, служит ключевое слово defined?
(обратите внимание на вопросительный знак в конце слова):
if defined? some_var
puts "some_var = #{some_var}"
else
puts "Переменная some_var неизвестна."
end
Аналогично метод respond_to?
выясняет, может ли объект отвечать на вызов указанного метода (то есть определен ли данный метод для данного объекта). Метод respond_to?
определен в классе Object
.
В Ruby запрос информации о типе во время выполнения поддерживается очень полно. Тип или класс объекта можно определить, воспользовавшись методом type
(из класса Object
). Метод is_a?
сообщает, принадлежит ли объект некоторому классу (включая и его суперклассы); синонимом служит имя kind_of?
. Например:
puts "abc".class "" # Печатается String
puts 345.class # Печатается Fixnum
rover = Dog.new
print rover.class # Печатается Dog
if rover.is_a? Dog
puts "Конечно, является."
end
if rover.kind_of? Dog
puts "Да, все еще собака."
end
if rover.is_a? Animal
puts "Да, он к тому же и животное."
end
Можно получить полный список всех методов, которые можно вызвать для данного объекта. Для этого предназначен метод methods
из класса Object
. Имеются также его варианты private_instance_methods
, public_instance_methods
и т.д.
Аналогично можно узнать, какие переменные класса или экземпляра ассоциированы с данным объектом. По самой природе ООП в перечни методов и переменных включаются те, что определены как в классе самого объекта, так и во всех его суперклассах. В классе Module
имеется метод constants
, позволяющий получить список всех констант, определенных в модуле.
В классе Module
есть метод ancestors
, возвращающий список модулей, включенных в данный модуль. В этот список входит и сам данный модуль, то есть список, возвращаемый вызовом Mod.ancestors
, содержит по крайней мере элемент Mod
. В этот список входят не только родительские классы (отобранные в силу наследования), но и «родительские» модули (отобранные в силу включения).
В классе Object
есть метод superclass
, который возвращает суперкласс объекта или nil
. Не имеет суперкласса лишь класс Object
, и, значит, только для него может быть возвращен nil
.
Модуль ObjectSpace
применяется для получения доступа к любому «живому» объекту. Метод _idtoref
преобразует идентификатор объекта в ссылку на него; можно считать, что это операция, обратная той, что выполняет двоеточие в начале имени. В модуле ObjectSpace
есть также итератор each_object
, который перебирает все существующие в данный момент объекты, включая и те, о которых иным образом узнать невозможно. (Напомним, что некоторые неизменяемые объекты небольшого размера, например принадлежащие классам Fixnum
, NilClass
, TrueClass
и FalseClass
, не хранятся в куче из соображений оптимизации.)
- 9.4 Локальное и удаленное зеркальное отражение
- 1.2.4. Отражение материального мира
- Глава 4. Отражение бухгалтерских операций в программе «Оперативная работа»
- Отражение атак
- 8.2.1. Отражение в учете расходных операций по кассе
- Формирование документов и отражение данных в складском учете
- 14.8. Эффектное отражение в воде
- ОТРАЖЕНИЕ ВАШЕЙ ЭКСПЕРТНОСТИ
- 11.2.1. Отражение затрат, образующихся в результате хозяйственной деятельности предприятия
- Зеркальное отражение