2015-11-03 95 views
1

我试图解决一个有错误的包中添加软件包别名,而无需修改源:如何通过猴子修补

  • Treex::PML::Schema::Container.pm长的子程序,包含两个不存在的包Treex::PML::FSFactory。它应该是Treex::PML::Factory
  • 有问题的子程序太长以至于无法从另一个文件复制和修补,所以我想猴子补丁Treex::PML,以便它提供Treex::PML::FSFactory作为Treex::PML::Factory的别名。

在我的主程序我尝试以下(基于this recipe),但它似乎没有任何效果:

use Treex::PML; 
package Treex::PML; 
use Package::Alias FSFactory => 'Treex::PML::Factory'; 

package MyPackage; 
... 

我怎样才能得到Treex::PML::FSFactory春天开始存在,在这样的一种可以被Treex::PML::Schema::Container看到的方式?

编辑:这个特殊的错误在我的错误报告的几个小时内得到修复!但是,无论如何知道如何使用别名都很有用。尽管我通过子类化解决了我的问题,但正如接受的答案所建议的那样,我已经添加了一个自我回答,显示如何使用别名完成它。

+1

你为什么不提交错误报告?我怀疑作者是社区活跃成员@choroba。 – ikegami

+0

我也会这样做,谢谢。 CTAN告诉我,作者是Petr Pajas,他最近与我联系了相关的isssues(我正在摔跤的应用程序) - 没有回应。但我现在看到,谷歌已经把我送到PML的旧版本。 @choroba已经接管了。 – alexis

+0

如果您在*使用Treex :: PML之前执行此操作,您的初始尝试是否有效? – ysth

回答

3

鉴于问题的参考,

$content = Treex::PML::FSFactory->createSeq(...) 
$content = Treex::PML::FSFactory->createList(...) 

添加下面的应该是足够了:

{ 
    package Treex::PML::FSFactory; 
    our @ISA = qw(Treex::PML::Factory); 
} 

我检查,如果Treex::PML::Factory::createSeqTreex::PML::Factory::createList心灵通过一个子类被称为,他们不知道;他们完全无视他们的主张。

+0

谢谢,好主意,但它没有奏效。任何想法为什么?我猜''FSFactory'的定义在Container :: validate_object()里面是不可见的,但我对perl命名空间的语义一无所知 - 我可能是错的。我不知道它是否相关,但是我在代码中使用了“使用Treex :: PML;”的单独实例(在别处需要)。 – alexis

+0

软件包全球存在。这不是一个可见性问题。这可能是一个计时问题。你可能已经做得太晚了。你甚至可能需要一个'BEGIN'。通过在'@ ISA'的任务旁边添加一个'print'可以方便地进行检查。 – ikegami

+0

你能否解释一下我必须注意什么才能获得正确的时机?该代码与调用Container中的越野车功能的子例程位于相同的文件中(以及上方)。 – alexis

1

@ ikegami的建议,派生类而不是别名,工作得很好。但是,这里也是如何将一个包名称别名到另一个,如问题所示:

a。用Package::Alias

use Package::Alias 'Treex::PML::FSFactory' => 'Treex::PML::Factory'; 

b。为避免从cpan下载Package::Alias,我遵循this recipe,它显示了Package::Alias实际上是如何实现的。它的工作原理:-)

*Treex::PML::FSFactory:: = \*Treex::PML::Factory::;