Как лучше переопределить / обернуть основные функции, такие как sysread, когда они вызываются в другом пакете - PullRequest
4 голосов
/ 20 мая 2011

Я работаю над довольно сложным приложением, написанным на Perl.У меня довольно большой опыт работы с языком, но я просто озадачен этим.

Я использую модуль Foo, который использует sysread и syswrite для различных операций над дескриптором файла (Направленный сокет, в данном случае), который я передаю его конструктору.

Я хочу сделать следующее: Из другого модуля, который я пишу (давайте назовем его Bar), я хочу изменить способ, которым используется sysread /write ведут себя только при вызове изнутри методов, принадлежащих Foo

Sysread и др. должны работать как обычно везде.Можно смело предположить, что использование sysread не изменится в Foo.

Причина Я хочу сделать это, мне нужно отслеживать количество байтов, которые читаются / записываютсяна вышеупомянутый дескриптор файла.На данный момент кажется, что это единственный способ получить эту информацию - в основном сохранение возвращаемого значения из sysread / write.

У меня нет проблем с использованием чего-либо из CPAN, если оно хорошего качества.


Обновление: я нашел лучшее решение для своей конкретной проблемы и разместил код здесь:

https://github.com/Hercynium/Tie-Handle-CountChars

Кажется, он работает очень хорошов моем приложении, но я не буду публиковать его в CPAN до тех пор, пока не провожу более тщательную проверку, а также не напишу несколько реальных модульных тестов:)

1 Ответ

2 голосов
/ 20 мая 2011

Вы можете сделать это, создав собственную функцию Foo :: sysread, которая оборачивает основную функцию, регистрируя возвращаемое значение. Обтекание может быть выполнено автоматически (не позволяя вам возиться с таблицей символов самостоятельно) с помощью Class :: Method :: Modifiers :

package Foo;

use strict;
use warnings;

# ... other code...

use Class::Method::Modifiers;
around sysread => sub {
    my $orig = shift;

    my $return = CORE::sysread(@_);

    # do something with $return

    return $return;
};
...