Как подделать Perl-модуль для зависимости?
Внешняя библиотека Perl, которую я использую, имеет зависимость (DBD::mysql), которую я не буду использовать в своем приложении (DBD::SQLite), поэтому я хотел бы, чтобы система просто притворилась, что зависимость есть, даже если она подделка".
Могу ли я просто создать пустой модуль DBD::mysql.pm, который компилируется, или есть более простой способ сделать это?
1 ответ
Поэтому я думаю, что здесь мало вопросов.
Когда вы говорите о зависимости, вы имеете в виду, что внешний модуль просто пытается require
или же use
DBD::mysql
? Если это так, то вы должны сообщить разработчику, что он не должен делать это явно, потому что это противоречит цели использования DBI
, Драйвер базы данных должен быть выбран на лету на основе DSN.
Предполагая, что автор просто use
Что касается имени пакета, потому что он считает, что это полезно или полезно, то да, вы можете переопределить этот пакет, и есть несколько способов сделать это.
Как вы предложили, вы можете просто создать свой собственный модуль DBD/mysql.pm
что бы определить DBD::mysql
пакет.
Есть некоторые другие вещи, которые вы могли бы сделать, если вы заинтересованы. Вместо того, чтобы засорять ваше исходное дерево поддельными каталогами и файлами, вам просто нужно убедить Perl, что модуль был загружен. Мы можем сделать это, непосредственно манипулируя %INC
,
package main; # or whereever
BEGIN {
$INC{'DBD/mysql.pm'} = "nothing to see here";
}
Просто добавив этот хэш-ключ, мы исключаем поиск в файловой системе модуля, вызывающего сбой. Обратите внимание, что это в BEGIN
блок. Если внешний автор сделал use
тогда мы должны заполнить это значение до того, как use
Заявление оценивается. use
заявления эквивалентны require
а также import
завернутый в BEGIN
,
Теперь давайте продолжим рассуждать в общем смысле, что внешний автор пытался вызвать методы пакета. Вы получите ошибки времени выполнения, если эти символы не существуют. Вы можете воспользоваться Perl's AUTOLOAD
перехватывать такие звонки и делать правильные вещи. То, что правильно, может сильно варьироваться, от простой записи сообщения до чего-то более сложного. Например, вы можете использовать эту возможность для проверки глубины связи, которую автор ввел, отслеживая все вызовы.
package DBD::mysql;
sub AUTOLOAD {
printf(
"I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0)
);
}
package main; # or whereever
BEGIN {
$INC{'DBD/mysql.pm'} = "nothing to see here";
}
DBD::mysql::blah()
Теперь давайте также рассмотрим случай, когда автор-нарушитель также создал несколько объектно-ориентированных экземпляров класса, и его код неправильно учитывает код заглушки. Мы заглушим конструктор, который мы предполагаем new
просто благословить анонимный хэш с именем нашего пакета. Таким образом, вы не получите ошибок, когда он вызывает методы в экземпляре.
package DBD::mysql;
sub AUTOLOAD {
printf(
"I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0)
);
}
sub new {
bless({}, __PACKAGE__)
}
package main; # or whereever
BEGIN {
$INC{'DBD/mysql.pm'} = "nothing to see here";
}
my $thing = new DBD::mysql;
$thing->blah()