我正在使用的外部Perl库有一个我不会在我的应用程序中使用的依赖项(DBD :: mysql)(DBD :: SQLite),所以我希望系统只是假装依赖存在,即使它是“假的”。
我是否可以创建一个空的DBD :: mysql.pm模块来编译或者有更直接的方法吗?
答案 0 :(得分:8)
所以我认为这里几乎没有问题。
当你说依赖时,你是说外部模块只是尝试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()