Perl:如何从基类导入子程序?

标签 perl oop inheritance import base

我有一个名为 Foo::Base 的基类,我需要继承它的方法,比如“new”,并在一个范围内导入一些子例程名称:

package Foo::Base;

sub new { ... }

sub import {
    no strict 'refs';

    my $caller = caller;

    *{"${caller}::my_sub"} = sub { 1 };
}

1;

所以,我需要在我的第二堂课 Foo::Child 中使用这个基类:
use base 'Foo::Base';

...并且它适用于继承,但它不会在范围内导入“my_sub”。我可以添加字符串
use Foo::Base;

对于它,它有帮助,但我不想写这样的东西:
use base 'Foo::Base';
use Foo::Base;

这看起来有点奇怪......这个问题有什么建议吗?

最佳答案

有两个原因可能想要做你正在做的事情,它们都是不好的。

首先是你试图从你的父类中导入方法......出于某种原因。也许你误解了 OO 的工作原理。你不需要这样做。只需将继承的方法称为方法,除非这些方法正在做一些古怪的事情,否则它将正常工作。

更有可能这是一个混合使用的模块,其中一些是方法,一些是导入的函数。为此,您可以...

use base 'Foo::Base';
use Foo::Base;

你正确地观察到它看起来有点奇怪......因为它有点奇怪。一个也导出的类是混合成语,这将导致奇怪的使用模式。

最好的办法是重新设计类而不是导出函数,或者将函数拆分到它们自己的模块中,或者使它们成为类方法。如果这些功能真的与类没有太大关系,那么最好将它们分离出来。如果它们确实与类有关,则将它们设为类方法。
use base 'Foo::Base';

Foo::Base->some_function_that_used_to_be_exported;

这消除了接口(interface)不匹配,并且作为奖励,子类可以像任何其他方法一样覆盖类方法行为。
package Bar;

use base 'Foo::Base';

# override
sub some_function_that_used_to_be_exported {
    my($class, @args) = @_;

    ...do something extra maybe...

    $class->SUPER::some_function_that_used_to_be_exported(@args);

    ...and maybe something else...
}

如果您无法控制基类,您仍然可以通过编写一个将导出的函数转换为方法的子类来使接口(interface)更加健全。
package SaneFoo;

use base 'Foo::Base';

# For each function exported by Foo::Base, create a wrapper class
# method which throws away the first argument (the class name) and
# calls the function.
for my $name (@Foo::Base::EXPORT, @Foo::Base::EXPORT_OK) {
    my $function = Foo::Base->can($name);
    *{$name} = sub {
        my $class = shift;
        return $function->(@_);
    };
}

关于Perl:如何从基类导入子程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12978971/

相关文章:

Perl:是否保证对常量的单一评估?

Perl Redis 监听不订阅 channel

perl - 在 Perl 中, ||运算符(operator)工作?

javascript - RemoveEventListener 不删除事件

c# - 从 C# 中的结构继承的梦想

string - 均匀分布重复字符串

python - 使用静态方法有什么好处?

ios - iOS 中 Setter 和 Getter 的来龙去脉?

c++ - 如何与另一个继承类的继承类对话

c# - 应该覆盖哪些方法才能正确继承 `ObservableCollection`