- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование на языке Ruby - Хэл Фултон
Шрифт:
Интервал:
Закладка:
end
p Alpha::FOO # "В Alpha нет FOO"
p Beta::FOO # "В Beta нет FOO"
p A::FOO # "В Alpha нет FOO"
p В::FOO # "В Beta нет FOO"
11.3.7. Удаление определений
Вследствие динамичности Ruby практически все, что можно определить, можно и уничтожить. Это может пригодиться, например, для того, чтобы «развязать» два куска кода в одной и той же области действия, избавляясь от переменных после того, как они были использованы. Другой повод — запретить вызовы некоторых потенциально опасных методов. Но по какой бы причине вы ни удаляли определение, делать это нужно крайне осторожно, чтобы не создать себе проблемы во время отладки.
Радикальный способ уничтожить определение — воспользоваться ключевым словом undef (неудивительно, что его действие противоположно действию def). Уничтожать можно определения методов, локальных переменных и констант на верхнем уровне. Хотя имя класса — тоже константа, удалить определение класса таким способом невозможно.
def asbestos
puts "Теперь не огнеопасно"
end
tax =0.08
PI = 3
asbestos
puts "PI=#{PI}, tax=#{tax}"
undef asbestos
undef tax
undef PI
# Любое обращение к этим трем именам теперь приведет к ошибке.
Внутри определения класса можно уничтожать определения методов и констант в том же контексте, в котором они были определены. Нельзя применять undef внутри определения метода, а также к переменной экземпляра.
Существуют (определены в классе Module) также методы remove_method и undef_method. Разница между ними тонкая: remove_method удаляет текущее (или ближайшее) определение метода, a undef_method ко всему прочему удаляет его и из суперклассов, не оставляя от метода даже следа. Это различие иллюстрирует листинг 11.6.
Листинг 11.16. Методы remove_method и undef_methodclass Parent
def alpha
puts "alpha: родитель"
end
def beta
puts "beta: родитель"
end
end
class Child < Parent
def alpha
puts "alpha: потомок"
end
def beta
puts "beta: потомок"
end
remove_method :alpha # Удалить "этот" alpha.
undef_method :beta # Удалить все beta.
end
x = Child.new
x.alpha # alpha: родитель
x.beta # Ошибка!
Метод remove_const удаляет константу.
module Math
remove_const :PI
end
# PI больше нет!
Отметим, что таким способом можно удалить и определение класса (потому что идентификатор класса — это просто константа):
class BriefCandle
#...
end
out_out = BriefCandle.new
class Object
remove_const :BriefCandle
end
# Создать еще один экземпляр класса BriefCandle не получится!
# (Хотя out_out все еще существует...)
Такие методы, как remove_const и remove_method, являются закрытыми (что и понятно). Поэтому во всех примерах они вызываются изнутри определения класса или модуля, а не снаружи.
11.3.8. Получение списка определенных сущностей
API отражения в Ruby позволяет опрашивать классы и объекты во время выполнения. Рассмотрим методы, имеющиеся для этой цели в Module, Class и Object.
В модуле Module есть метод constants, который возвращает массив всех констант, определенных в системе (включая имена классов и модулей). Метод nesting возвращает массив всех вложенных модулей, видимых в данной точке программы.
Метод экземпляра Module#ancestors возвращает массив всех предков указанного класса или модуля.
list = Array.ancestors
# [Array, Enumerable, Object, Kernel]
Метод constants возвращает список всех констант, доступных в данном модуле. Включаются также его предки.
list = Math.constants # ["E", "PI"]
Метод class_variables возвращает список всех переменных класса в данном классе и его суперклассах. Метод included_modules возвращает список модулей, включенных в класс.
class Parent
@@var1 = nil
end
class Child < Parent
@@var2 = nil
end
list1 = Parent.class_variables # ["@@var1"]
list2 = Array.included_modules # [Enumerable, Kernel]
Методы instance_methods и public_instance_methods класса Class — синонимы; они возвращают список открытых методов экземпляра, определенных в классе. Методы private_instance_methods и protected_instance_methods ведут себя аналогично. Любой из них принимает необязательный булевский параметр, по умолчанию равный true; если его значение равно false, то суперклассы не учитываются, так что список получается меньше.
n1 = Array.instance_methods.size # 121
n2 = Array.public_instance_methods.size # 121
n3 = Array.private_instance_methods.size # 71
n4 = Array.protected_instance_methods.size # 0
n5 = Array.public_instance_methods(false).size # 71
В классе Object есть аналогичные методы, применяющиеся к экземплярам (листинг 11.17). Метод methods возвращает список всех методов, которые можно вызывать для данного объекта. Метод public_methods возвращает список открытых методов и принимает параметр, равный по умолчанию true, который говорит, нужно ли включать также методы суперклассов. Методы private_methods, protected_methods и singleton_methods тоже принимают такой параметр.
Листинг 11.17. Отражение и переменные экземпляраclass SomeClass
def initialize
@a = 1
@b = 2
end
def mymeth
# ...
end
protected :mymeth
end
x = SomeClass.new
def
x.newmeth
# ...
end
iv = x.instance_variables # ["@b", "@a"]
p x.methods.size # 42
p x.public_methods.size # 41
p x.public_methods(false).size # 1
p x.private_methods.size # 71
p x.private_methods(false).size # 1
p x.protected_methods.size # 1
p x.singleton_methods.size # 1
Если вы работаете с Ruby уже несколько лет, то заметите, что эти методы немного изменились. Теперь параметры по умолчанию равны true, а не false.
11.3.9. Просмотр стека вызовов
And you may ask yourself:Well, how did I get here?[13]
Talking Heads, «Once in a Lifetime»Иногда необходимо знать, кто вызвал метод. Эта информация полезна, если, например, произошло неисправимое исключение. Метод caller, определенный в модуле Kernel, дает ответ на этот вопрос. Он возвращает массив строк, в котором первый элемент соответствует вызвавшему методу, следующий — методу, вызвавшему этот метод, и т.д.
def func1
puts caller[0]
end
def func2
func1
end
func2 # Печатается: somefile.rb:6:in 'func2'
Строка имеет формат «файл;строка» или «файл;строка в методе».
11.3.10. Мониторинг выполнения программы
Программа на Ruby может следить за собственным выполнением. У этой возможности есть много применений; интересующийся читатель может заглянуть в исходные тексты программ debug.rb, profile.rb и tracer.rb. С ее помощью можно даже создать библиотеку для «проектирования по контракту» (design-by-contract, DBC), хотя наиболее популярная в данный момент библиотека такого рода этим средством не пользуется.
Интересно, что этот фокус реализован целиком на Ruby. Мы пользуемся методом set_trace_func, который позволяет вызывать указанный блок при возникновении значимых событий в ходе исполнения программы. В справочном руководстве описывается последовательность вызова set_trace_func, поэтому здесь мы ограничимся простым примером:
def meth(n)
sum = 0
for i in 1..n
sum += i
end
sum
end
set_trace_func(proc do |event, file, line,
id, binding, klass, *rest|
printf "%8s %s:%d %s/%sn", event, file, line,
klass, id
end)
meth(2)
Отметим, что здесь соблюдается стандартное соглашение о заключении многострочного блока в операторные скобки do-end. Круглые скобки обязательны из-за особенностей синтаксического анализатора Ruby. Можно было бы, конечно, вместо этого поставить фигурные скобки.

