3

我正在使用的外部 Perl 库有一个依赖项(DBD::mysql),我不会在我的应用程序(DBD::SQLite)中使用它,所以我希望系统只是假装依赖项在那里,即使它是假的”。

我可以只创建一个空的 DBD::mysql.pm 模块来编译还是有更直接的方法来做到这一点?

4

1 回答 1

8

所以我认为这里的问题很少。

当您说依赖时,您的意思是外部模块只是尝试requireoruse 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语句等效于 arequireimport包含在 a 中BEGIN

现在让我们进一步推测外部作者试图调用包的方法。如果这些符号不存在,您将收到运行时错误。您可以利用 PerlAUTOLOAD拦截此类调用并做正确的事情。什么是正确的事情可以有很大的不同,从简单的记录消息到更复杂的事情。例如,您可以使用此工具通过监视所有调用来检查作者引入的耦合深度。

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()
于 2011-06-29T05:07:37.623 回答