LINUX.ORG.RU

Патчи на методы класса/объекта или «есть ли в природе рантайм-дебагеры»

 , , ,


2

5

Хотелось бы что-то вроде такого:

«После того, как неинициализированной переменной $a будет присвоено значение, вызвать вот такой метод объекта».

Поясню смысл:

Я могу наследовать объект, это прекрасно.

Я могу всячески переопределять его методы и свойства, даже ломая всю логику исходного объекта, которому наследую... Ну, положим, это менее прекрасно.

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

Мне, конечно, хотелось бы вставить внутрь такого объекта breakpoint, но... а что если протоколируемая ситуация происходит только в рантайме при невыясненных обстоятельствах? Или что если объект всячески использует обработчики событий, распараллеливание и пр. - и тоже интересная ситуация ни в каком дебагере не вылезает никогда, а вот в рантайме - вполне, и самым неприятным образом.

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

Почему это нужно? Почему нельзя просто переопределить метод после наследования?

Ответ простой: логика метода, как правило, не сильно меняется с течением времени, глобальный рефакторинг случается редко, и его легко заметить - поэтому достаточно высокоуровневое описание патча в духе «после инициализации переменной, сделай это» - переживёт обновления исходного класса с высокой долей вероятности. В конце-концов проблему несовместимости «патча» выявит как таковой «патчер» в языке - и либо просто не выполнит соотв. кусок кода, выдав при запуске ошибку (если проблема определяется на этапе компиляции), либо вывалит error в рантайме - плохо конечно, но для того и нужны регрессионные автотесты, чтобы предупреждать заранее подобные казусы. А вот если я переопределяю сам метод, исходно сделав тупо копипасту - то мне волей-не волей придётся потом следить за всеми «мутациями» кода класса, обновляя копипасту... и это как бы при том, что я НЕ являюсь его мейнтейнером (а может быть и не знаю его мейнтейнера)!

Хорошо, когда описанное можно сделать before или after hook'ом (например, в Perl5/Moose такие штуки есть), но плохо, когда в общем случае нужно всё-таки пропатчить объект в произвольном месте.

Вот как? Есть ли уже какие-то решения данной задачи? Насколько я отстал от жизни или почему мне не нужно то, что мне нужно?

Просветите, пожалуйста!

P.S.

Кстати, да, было бы ещё интересно не модифицировать класс, но модицифировать именно методы уже созданных инстансов класса, объектов то бишь. Ибо объектов 100500 штук и какие-то из них я хочу патчить, а какие-то - совершенно не хочу, даром не надо.

★★★★★

Последнее исправление: DRVTiny (всего исправлений: 8)

Ответ на: комментарий от no-such-file

В том конкретном случае, который есть сейчас - для отладки. Но часто реально нужно бывает те же логи писать по-человечески, поскольку разработчикам как правило лень этим заниматься.

DRVTiny ★★★★★
() автор топика

а вот если бы ты использовал Java, то с помощью «java agent» можно было бы сделать редефайн метода и приписать ему в самый конец что-нгибудь

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

В конец легко и на Modern Perl'е (ну правда не в контексте метода, просто этаким «мутатором-after-хуком»).

Интересно, кстати, может, в Perl6 уже можно. Там если оно поднялось после минуты прогрева на старте - то уже умеет почти всё, что должен уметь язык, хотя и мало из того, что должен иметь язык (в качестве библиотечного приданного).

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Тогда мне нужно ради 0.0001% функционала запускать приложение в дебагере :(

Сразу вспомнилось, что в Gtk3 как раз добавили runtime inspector (Ctrl-Shift-I). И такую инфу в дебагере собрать было бы непросто.

gag ★★★★★
()

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

Так есть же :before, :after, :around (см. http://www.aiai.ed.ac.uk/~jeff/clos-guide.html последняя глава).

monk ★★★★★
()

... было бы ещё интересно не модифицировать класс, но модицифировать именно методы уже созданных инстансов класса, ...

«практикал коммон лисп», глава 16, в частности, твой пример - ищи *account-of-bank-president*. если нужен на русском - тереби архимага, т.к. лиспер.ру сдох месяца 3 назад

т.е. в терминах лиспа твоя задача решается созданием :after метода с eql специализатором для райтера или акцессора слота требуемого объекта

anonymous
()
Ответ на: комментарий от stevejobs

... сделать редефайн метода ...

а в лиспе можно не трогая метода выполнить что-нибудь перед методом и что-нибудь-2 после. причем, делается это стандартным способом и описано в учебнике для новичков

anonymous
()
Ответ на: комментарий от monk

:before, :after, :around

ТС хочет большего - воткнуть свой код внутрь метода.

Вообще в лиспе такой финт ушами можно сделать - взять код функции через function-lambda-expression, распарсить, воткнуть свой код, переопределить функцию новым кодом. Но это какой-то БДСМ.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

А чем его тогда не устраивает patch?

Это не спортивно не в рантайме.

no-such-file ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.