为非对象perl模块复制base / parent.pm功能的最简洁方法是什么?

前端之家收集整理的这篇文章主要介绍了为非对象perl模块复制base / parent.pm功能的最简洁方法是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我现在不太清楚,可能会忽略一些简单的事情.我已经考虑了一段时间并一直在寻找,但不能再想到任何明智的搜索查询会导致我找到我想要的东西.

简而言之,我想知道如何进行模块继承,就像base.pm/parent.pm为面向对象模块做的那样;仅适用于基于Exporter的模块.

我的意思的一个假设的例子:

这是我们的脚本.它最初加载了Foo.pm并从中调用了baz(),但是baz()有一个可怕的bug(我们很快就会看到),所以我们现在使用Local / Patched / Foo.pm来解决这个问题.我们这样做,因为在这个假设的情况下我们不能改变Foo(它是一个正在积极开发的cpan模块,你看),并且它是巨大的(严重的).

  1. #!/usr/bin/perl
  2.  
  3. # use Foo qw( baz [... 100 more functions here ...] );
  4. use Local::Patched::Foo qw( baz [... 100 more functions here ...] );
  5. baz();

这是Foo.pm.正如你所看到的,它导出了调用qux的baz(),它有一个可怕的bug,导致事情崩溃.我们希望保留baz和Foo.pm的其余部分,但没有做大量的复制粘贴,特别是因为它们可能会在以后更改,因为Foo仍在开发中.

  1. package Foo;
  2. use parent 'Exporter';
  3. our @EXPORT = qw( baz [... 100 more functions here ...] );
  4. sub baz { qux(); }
  5. sub qux { print 1/0; } # !!!!!!!!!!!!!
  6. [... 100 more functions here ...]
  7. 1;

最后,由于Foo.pm用于很多地方,我们不想使用Sub :: Exporter,因为这意味着将bandaid修复程序复制粘贴到所有这些地方.相反,我们正在尝试创建一个新的模块,其行为和看起来像Foo.pm,并且实际上仍然从Foo.pm加载其99%的功能,并用更好的一个替换丑陋的qux子.

接下来是如果Foo.pm是面向对象的,那么这样的事情会是什么样子:

  1. package Local::Patched::Foo;
  2. use parent 'Foo';
  3. sub qux { print 2; }
  4. 1;

现在这显然不适用于我们目前的情况,因为parent.pm只是不做这种事情.

是否有一种干净而简单的方法来编写Local / Patched / Foo.pm(使用任何适用的CPAN模块),这种方法可以工作,而不是手动复制Foo.pm的函数命名空间?

解决方法

只是添加了另一种方法来修补Foo的qux函数,这个没有任何手动typeglob操作.
  1. package Local::Patched::Foo;
  2. use Foo (); # load but import nothing
  3.  
  4. sub Foo::qux {
  5. print "good qux";
  6. }

这是有效的,因为Perl的包总是可变的,只要上面的代码在加载Foo.pm后出现,它就会覆盖现有的baz例程.你可能也不需要警告’重新定义’;沉默任何警告.

然后使用它:

  1. use Local::Patched::Foo;
  2. use Foo qw( baz );
  3.  
  4. baz(); # calls the patched qux() routine

您可以通过在Local :: Patched :: Foo中编写自定义导入方法来消除这两个使用行,如下所示:

  1. # in the Local::Patched::Foo package:
  2.  
  3. sub import {
  4. return unless @_; # return if no imports
  5. splice @_,1,'Foo'; # change 'Local::Patched::Foo' to 'Foo'
  6. goto &{ Foo->can('import') }; # jump to Foo's import method
  7. }

然后就是:

  1. use Local::Patched::Foo qw( baz );
  2.  
  3. baz(); # calls the patched qux()

猜你在找的Perl相关文章