> -- Info21 писал(а):
> Основной вопрос: какой тут выбрать механизм для внешнего представления такого обхода: итератор (навроде прохода по вложенным вьюшкам в контейнере) -- или рассылка сообщений.Я на работе в программу прошлым летом встроил обход всех объектов. Понадобилось для контроля над утечками памяти. Теперь всегда знаю сколько в памяти объектов какого типа есть, скорость их создания и удаления.

Написал модуль Diagnostics. Там абстрактный указательный тип Diagnostics.Object. У него переопределяемая процедура без параметров Traverse. Она экспортируется только для реализации. Ещё экспортируется просто процедура Diagnostics.TraverseThis(obj: Diagnostics.Object). В переопределённой процедуре Diagnostics.Object.Traverse() надо вызвать процедуру Diagnostics.TraverseThis(obj) для каждого диагностируемого объекта видимого из данного. У каждого Diagnostics.Object есть счётчик эпох обхода (целое число). Новый обход инициируется вызовом процедуры Diagnostics.TraverseRoot(root: Diagnostics.Object). Она увеличивает глобальный счётчик обходов на единицу, записывает его в root, ставит root в глобальную очередь. Затем, пока эта очередь не пуста вытаскивает из неё объекты и вызывает у них виртуальную Traverse. В ней вызываются Diagnostics.TraverseThis(obj) они сравнивают счётчик эпох обхода с текущим значением, если равен, значит этот объект уже был в пройден, иначе добавляем в очередь обхода.

Diagnostics.TraverseRoot глобально лочится и проверяет на повторное вхождение чтоб в один момент времени был активен только один обход.

Если нужно выполнить какое-то обобщённое действие, единственное что нужно, так это добавить в процедуру Traverse аргумент - "визитёртку". Мне он не нужен был.