2009-07-22 4 views
3

L'héritage multiple est excellent, et Perl le gère très bien tant que vous avez une compréhension claire de votre hiérarchie d'héritage et de certains des pièges potentiels (tels que ceux décrits dans perldoc perltoot). Pourtant, il ne traite pas de l'interdiction d'utiliser le pragma fields avec l'héritage multiple. En effet, je ne trouve aucune documentation sur ce que ce soit ...Pourquoi les champs pragma sont-ils incompatibles avec l'héritage multiple en Perl?

est ici une illustration:

package Parent1; 
use fields 'field1'; 

package Parent2; 
use fields 'field2'; 

package Child; 
use base qw(Parent1 Parent2); 

Cela échoue avec l'erreur: « ne peut pas hériter des champs à plurisubstitués ... »

Cela ne fonctionne pas même lorsque les deux parents ont les mêmes champs .. même quand ils sont prouvablement les mêmes, parce qu'ils viennent d'un grand-parent commun:

package Grandparent; 
use fields qw(field1); 

package Parent1; 
use base 'Grandparent'; 

package Parent2; 
use base 'Grandparent'; 

package Child; 
use base qw(Parent1 Parent2); 

Un inconvénient pour implémenter cela correctement est l'invariant que l'index d'un champ dans un objet enfant est toujours le même que l'index dans son parent. Je ne suis pas sûr que cette exigence soit vraiment nécessaire, cependant ... Contrairement à C++, où un objet peut être accédé en utilisant un pointeur typé à un parent, Perl connaît toujours le type réel d'un objet en opérant sur sa référence (en effet champs pseudohash est essentiellement un vtable, conservé sur chaque instance d'objet). Et en particulier dans le deuxième exemple ci-dessus, les champs hérités de chaque parent proviennent de les deux parents, donc ils peuvent être repliés ensemble et il n'y a pas d'index conflictuel.

Je suis sûr qu'il y a d'autres problèmes aussi, mais je ne les ai pas encore trouvés.

Quelqu'un peut-il avoir des connaissances sur les internes de Perl?

+0

Vous ne pouvez pas avoir deux parents, et utilisez 'fields', vous devez trouver un autre paquet sur CPAN –

+0

Um, merci ... ce n'était pas tout le point de mon message? – Ether

+0

@Ether - pourquoi pas de réponse acceptée? Thx :) – DVK

Répondre

4

1) Vous pouvez essayer d'utiliser la délégation au lieu de l'héritage, as described here. 2) De plus, une documentation (incluant le lien ci-dessus) semble impliquer que le problème avec l'héritage multiple est dû aux pseudo-hashs. Perl 5.10 a changé l'implémentation de "fields" pragma en quelque chose d'autre que des pseudo-hashs - si c'est une option, essayez l'approche que vous avez utilisée dans Perl5.10 et cela pourrait fonctionner (je n'ai pas accès à 5.10 donc je ne peux pas expérimenter, désolé)

PS En ce qui concerne "je ne peux trouver aucune documentation à ce sujet ..." - au moins une mention dans la documentation "officielle" est une citation du livre de Camel ("Programmation Perl", série Perl d'O'Reilly), 3ème édition, chapitre 31.3. "use base":

"Multiple inheritance of field classes is not supported. The use base pragma raises an exception if more than one named base class has fields."

+1

Cela ne fonctionne pas non plus dans Perl 5.10. –

3

Les champs pragma étaient une expérience intéressante, mais à mon avis, un échec. C'est la fonctionnalité la plus utile, compiler la vérification de temps des clés de hachage d'attribut, a été retiré en 5.10. Il y a un certain nombre de modules de composition de classe décents sur le CPAN, ainsi que le poids lourd mais de plus en plus en popularité Moose ("Un système d'objet postmoderne pour Perl 5"). Cela dit, si vous vouliez faire un effort pour ajouter un support d'héritage multiple, il serait probablement le bienvenu; Notez que les champs sont maintenant maintenus indépendamment de perl dans le cadre du "base" distribution. Cependant, vous devrez le faire fonctionner avec les implémentations à base de pseudohash (pré-5.9.0) et à base de hachage restreint (5.9.0+).

Questions connexes