Как подделать Perl-модуль для зависимости? - PullRequest
3 голосов
/ 29 июня 2011

Внешняя библиотека Perl, которую я использую, имеет зависимость (DBD :: mysql), которую я не буду использовать в своем приложении (DBD :: SQLite), поэтому я хотел бы, чтобы система просто притворилась, что зависимость есть,даже если это «фальшивка».

Могу ли я просто создать пустой модуль DBD :: mysql.pm, который компилируется, или есть более простой способ сделать это?

1 Ответ

8 голосов
/ 29 июня 2011

Так что я думаю, что здесь мало вопросов.

Когда вы говорите о зависимости, вы имеете в виду, что внешний модуль просто пытается 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...