[Moscow.pm] функция не из нашего пакета

Vladimir V. Perepelitsa inthrax на gmail.com
Пн Дек 29 03:07:12 PST 2008


2008/12/29 Dmitry E. Oboukhov <unera на debian.org>:
>>> *{$name}=sub { &$c };
>
> VVP> зачем враппер?
> VVP> *$name = \&$c;
> ну потому что он содержит еще код, а в данном примере этот код не приведен :)
>
> профайлер свой делаю :)

тогда нужно было поставить троеточие :)

типа sub { ... &$c; ...}
кстати можешь еще заценить Sub::Uplevel. удобно писать врапперы.

>
>>> но если функция представляет собой константную функцию (например
>>> константы в каком-то модуле вроде Errno) то получаем варнинг про
>>> попытку переопределения константной функции
>>>
>>> Constant subroutine ...
>>>
>>> Я ковырялся в поисках директивы которая отменяет этот варнинг, но
>>> не нашел варианта. Так же не нашел можно ли по ссылке на функцию определить
>>> не константная ли она?
>>>
>>> сейчас тупо перехватил варнинг
>>> $SIG{__WARN__}=sub { $is_constant=1 if $_[0]=~/^Constant sub/ };
>
> VVP> константные сабы компилятся и их переопределение вызывает некоторые
> VVP> "неприятные" для интерпретатора операции.
> это понятно, поэтому хочется их как-то отделить от остальных
> и не переопределять

Думаю это можно сделать через XS.
у такой сабы должен быть выставлен какой-нибудь флажок.

>>> и после переопределения если $is_constant установлено в true то
>>> так вылавливаю константные ф-ции. хотелось бы от этого хака избавиться
>
> VVP> Вообще на мой взгляд делаете что-то странное :)
> VVP> Не хотите расписать задачу в более общем виде? Я так думаю есть более
> VVP> элегантное решение.
>
> ну обычная задача профайлинга:
> проходим по полному списку всех функций
> вешаем на них врапперы, измеряем время итп
>
> отсюда сразу растут следующие задачи:
> 1. одна функция может быть импортирована в кучу пакетов, соответственно
> ее надо (желательно) переопределить лишь один раз

дело в том, что после импорта, модуль-получатель функции, содержит
ссылку на исходную функцию.
поэтому переопределять придется везде.
либо нужно врапить функции в исходном пакете до вызова import.

PS: hint:
попробуйте заменить Exporter::import на собственную реализацию.
т.е. в самом начале сделайте:
use Exporter;
BEGIN {
  no warnings 'redefine';
  *Exporter::import = sub { ... };
}

> 2. хорошо бы именно импортированные алиасы отбросить
> 3. отделить константные функции и их не трогать
> 4. не конфликтовать с модулями которые сами делают аналогичную работу


-- 
Best wishes,
Vladimir V. Perepelitsa aka Mons <inthrax на gmail.com>


Подробная информация о списке рассылки Moscow-pm