719*_*016 3 perl dependencies perl-module dbd
我正在使用的外部Perl库有一个我不会在我的应用程序中使用的依赖项(DBD :: mysql)(DBD :: SQLite),所以我希望系统只是假装依赖存在,即使它是假的".
我可以创建一个空的DBD :: mysql.pm模块来编译或者有更简单的方法吗?
所以我认为这里几乎没有问题.
当你说依赖,你的意思是外部模块只是尝试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";
}
Run Code Online (Sandbox Code Playgroud)
只需添加此哈希键,我们就不会搜索有问题的模块的文件系统.观察到这是一个BEGIN块.如果外部作者执行了a,use那么我们必须在use评估语句之前填充此值.这些use陈述等同于a require并import包含在a中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()
Run Code Online (Sandbox Code Playgroud)
现在我们还要介绍一个违规作者还创建了一个类的面向对象实例的情况,并且他的代码没有正确地说明你的存根代码.我们将构造函数存根,我们假设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()
Run Code Online (Sandbox Code Playgroud)