为非对象perl模块复制base / parent.pm功能的最简洁方法是什么?
我现在不太清楚,可能会忽略一些简单的事情.我已经考虑了一段时间并一直在寻找,但不能再想到任何明智的搜索查询会导致我找到我想要的东西.
简而言之,我想知道如何进行模块继承,就像base.pm/parent.pm为面向对象模块做的那样;仅适用于基于Exporter的模块. 我的意思的一个假设的例子: 这是我们的脚本.它最初加载了Foo.pm并从中调用了baz(),但是baz()有一个可怕的bug(我们很快就会看到),所以我们现在使用Local / Patched / Foo.pm来解决这个问题.我们这样做,因为在这个假设的情况下我们不能改变Foo(它是一个正在积极开发的cpan模块,你看),并且它是巨大的(严重的). #!/usr/bin/perl # use Foo qw( baz [... 100 more functions here ...] ); use Local::Patched::Foo qw( baz [... 100 more functions here ...] ); baz(); 这是Foo.pm.正如你所看到的,它导出了调用qux的baz(),它有一个可怕的bug,导致事情崩溃.我们希望保留baz和Foo.pm的其余部分,但没有做大量的复制粘贴,特别是因为它们可能会在以后更改,因为Foo仍在开发中. package Foo; use parent 'Exporter'; our @EXPORT = qw( baz [... 100 more functions here ...] ); sub baz { qux(); } sub qux { print 1/0; } # !!!!!!!!!!!!! [... 100 more functions here ...] 1; 最后,由于Foo.pm用于很多地方,我们不想使用Sub :: Exporter,因为这意味着将bandaid修复程序复制粘贴到所有这些地方.相反,我们正在尝试创建一个新的模块,其行为和看起来像Foo.pm,并且实际上仍然从Foo.pm加载其99%的功能,并用更好的一个替换丑陋的qux子. 接下来是如果Foo.pm是面向对象的,那么这样的事情会是什么样子: package Local::Patched::Foo; use parent 'Foo'; sub qux { print 2; } 1; 现在这显然不适用于我们目前的情况,因为parent.pm只是不做这种事情. 是否有一种干净而简单的方法来编写Local / Patched / Foo.pm(使用任何适用的CPAN模块),这种方法可以工作,而不是手动复制Foo.pm的函数命名空间? 解决方法
只是添加了另一种方法来修补Foo的qux函数,这个没有任何手动typeglob操作.
package Local::Patched::Foo; use Foo (); # load but import nothing sub Foo::qux { print "good qux"; } 这是有效的,因为Perl的包总是可变的,只要上面的代码在加载Foo.pm后出现,它就会覆盖现有的baz例程.你可能也不需要警告’重新定义’;沉默任何警告. 然后使用它: use Local::Patched::Foo; use Foo qw( baz ); baz(); # calls the patched qux() routine 您可以通过在Local :: Patched :: Foo中编写自定义导入方法来消除这两个使用行,如下所示: # in the Local::Patched::Foo package: sub import { return unless @_; # return if no imports splice @_,1,'Foo'; # change 'Local::Patched::Foo' to 'Foo' goto &{ Foo->can('import') }; # jump to Foo's import method } 然后就是: use Local::Patched::Foo qw( baz ); baz(); # calls the patched qux() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |