覆盖Perl Class :: Accessor

时间:2015-05-09 15:46:23

标签: perl oop

前提

这个问题很难理解,因为我对OP的OO逻辑存在误解。这些评论有助于理解它。

原始问题

Class::Accessor模块对我来说非常方便,但我找不到任何关于如何编写构造函数的文档,例如,我可以从某些计算中导出字段的值。 / p>

在给定的文档中,我能想到的最接近的事情就是通过“一种”覆盖:

package FooHack;

...
use Class::Accessor 'antlers';
has something => ( is => 'ro' );

# Methods here...

package Foo; # Foo is a plain module, not a class.

sub new { 
    my $macguffin = &crunch_chop_summon;
    FooHack->new({something => $macguffin });
}

此类工作正常,但my $f = Foo->new(); say ref $f将产生FooHack而不是Foo

所以我的问题是:

  • 我的想法是否足够好,或者您是否看到了一些可能的问题?或者可能有一些改进?
  • 有没有更好的方法做同样的事情?

编辑:

这是 NOT 实际覆盖。 Foo无处可读。它只是一个声明sub new的普通模块。另外,模块FooHack不是外部模块。它在同一个文件中定义。

模块Foo假装是一个类,因为它遵循sub new的约定,而new实际上只是一个调用真实构造函数的函数{{1并传递一些初始化值。

2 个答案:

答案 0 :(得分:1)

TL; DR use Moose代替use Class::Accessor会有很大帮助,您不必更改{{1} }定义

正如我在评论中写的那样,您要求Class::Accessor - 一个可以轻松创建访问器方法的模块 - 提供面向对象功能的完整法定数量

我也认为你对面向对象继承的看法很混乱。我没有看到你写的内容有什么问题,但has作为Foo子类是错误的想法,并且让我和其他许多人一样困惑< / p>

应该有一个FooHack基类和可能有多个子类,例如FooFooHackFooPlus等。

答案 1 :(得分:0)

嗯,篡改这样的模块有点讨厌 - 如果它没有做你想要的,那么通常你只需要写一个新模块。

你可以上课并扩展它以创建一个新课程 - 如果所讨论的课程不能满足你的需要,那就是你通常会做的。应用hack来覆盖构造函数正在颠覆类维护者的期望,以及脆弱代码的道路,这就是为什么你不能轻易做到的。

那就是说 - 通常作为构造函数的一部分,你将调用bless来将对象实例化为一个类。按照惯例,这是使用new方法在当前类中完成的。但是没有真正的理由你不能:

my $self = {};
bless ( $self, 'Foo' ); 

请记住,如果你的构造函数不执行此对象期望发生的事情,那么你可能会破坏事物。