为什么字段pragma与Perl中的多重继承不兼容?

时间:2009-07-22 22:26:11

标签: perl inheritance module field

多重继承很棒,只要你清楚地了解你的继承层次和一些潜在的陷阱(比如perldoc perltoot中描述的那些),Perl就可以很好地处理它。然而,它没有讨论禁止将fields pragma用于多重继承。实际上,我找不到任何关于此的文件......

以下是插图:

package Parent1;
use fields 'field1';

package Parent2;
use fields 'field2';

package Child;
use base qw(Parent1 Parent2);

这失败并出现错误:“无法在...处继承字段继承”

即使父母双方都拥有相同的字段,这也不起作用。甚至当它们可证明相同时,因为它们来自共享的祖父母:

package Grandparent;
use fields qw(field1);

package Parent1;
use base 'Grandparent';

package Parent2;
use base 'Grandparent';

package Child;
use base qw(Parent1 Parent2);

正确实现这一点的一个缺陷是,子对象中字段的索引始终与其父对象中的索引相同。我不确定这个要求是否真的需要,但是...不像在C ++中,可以使用键入父类的指针来访问对象,Perl在对其引用进行操作时总是知道对象的实际类型(实际上fields pseudohash本质上是一个vtable,保存在每个对象实例上)。特别是在上面的第二个例子中,从每个父项继承的字段来自两个父项,因此它们可以折叠在一起并且没有冲突的索引。

我确定还有其他问题,但我还没有找到它们。

任何对Perl内部有一定了解的人都可以对此发表评论吗?

2 个答案:

答案 0 :(得分:4)

1)您可以尝试使用委托而不是继承as described here

2)另外,一些文档(包括上面的链接)似乎暗示多重继承的问题是由于伪聚类。 Perl 5.10将“fields”pragma的实现更改为除pseudohashes之外的其他内容 - 如果它是一个选项,请尝试在Perl5.10中使用的方法并且它可能正常工作(我没有访问5.10因此无法实验,遗憾)

P.S。关于“我找不到任何关于此的文档...” - 至少在“官方”文档中提到这一点是来自Camel书(“Perl编程”,O'Reilly的Perl系列),第3版,章节31.3。 “使用基地”:

  

“不支持字段类的多重继承。如果多个命名基类具有字段,则use pragma引发异常。”

答案 1 :(得分:3)

田野pragma是一个有趣的实验,但在我看来,一个失败的实验。在5.10中删除了最有用的功能,即对属性哈希键进行编译时检查。 CPAN上有许多体面的类组合模块,以及重量级但稳步增长的人气Moose(“Perl 5的后现代对象系统”)。

也就是说,如果你想努力增加多重继承支持,那么它可能会受到欢迎;请注意,现在,字段作为"base" distribution的一部分独立于perl维护。但是,您必须使用基于pseudohash(5.9.0之前)和受限制的基于哈希(5.9.0+)的实现。