Так что я думаю, что здесь мало вопросов.
Когда вы говорите о зависимости, вы имеете в виду, что внешний модуль просто пытается 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 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()