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

#perl #sockets #cpan #filehandle #symbol-tables

#perl #сокеты #cpan #Дескриптор файла #таблицы символов

Вопрос:

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

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

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

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

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

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


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

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

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

Комментарии:

1. мне пришло в голову, что я мог бы достичь своей цели, связав переменную filehandle. Я никогда не делал этого раньше — советы приветствуются — но я опубликую, если придумаю что-нибудь полезное.

2. работаем над возможным решением здесь: github.com/Hercynium/Tie-Handle-CountChars В нем все еще есть ошибка, а именно, что связанный дескриптор файла не закрывается должным образом, когда это сокет в anyevent.

Ответ №1:

Вы могли бы сделать это, создав свою собственную функцию 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;
};
  

Комментарии:

1. Я попробую это — я уже играл с Hook :: LexWrap и копался в таблице символов 🙂