Почему прагма fields несовместима с множественным наследованием в Perl?

Множественное наследование — это прекрасно, и Perl отлично с этим справляется, если у вас есть четкое представление о вашей иерархии наследования и некоторых потенциальных ловушках (например, описанных в perldoc perltoot). Однако в нем не обсуждается запрет на использование прагмы fields с множественным наследованием. Действительно, я не могу найти никаких документов об этом вообще...

Вот иллюстрация:

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 псевдохеш — это, по сути, виртуальная таблица, хранящаяся в каждом отдельном экземпляре объекта). В частности, во втором приведенном выше примере поля, унаследованные от каждого родителя, поступают от обоих родителей, поэтому их можно складывать вместе и не возникает конфликтующих индексов.

Я уверен, что есть и другие проблемы, но я их еще не нашел.

Может ли кто-нибудь, кто хоть немного разбирается во внутреннем устройстве Perl, прокомментировать это?


person Ether    schedule 22.07.2009    source источник
comment
Вы не можете иметь двух родителей и использовать fields, вам нужно найти какой-то другой пакет на CPAN   -  person Brad Gilbert    schedule 23.07.2009
comment
Хм, спасибо... разве не в этом был весь смысл моего поста?   -  person Ether    schedule 23.07.2009
comment
@Ether - почему нет принятого ответа? Спасибо :)   -  person DVK    schedule 08.10.2009
comment
Я искал лучшее решение. К сожалению, однако, я также начал использовать Moose, поэтому я не могу найти его...   -  person Ether    schedule 08.10.2009


Ответы (2)


1) Вы можете попробовать использовать делегирование вместо наследования, как описано здесь.

2) Кроме того, некоторая документация (включая ссылку выше), по-видимому, подразумевает, что проблема с множественным наследованием связана с псевдохешами. Perl 5.10 изменил реализацию прагмы «fields» на нечто иное, чем псевдохэши — если это возможно, попробуйте подход, который вы использовали в Perl 5.10, и он может сработать (у меня нет доступа к 5.10, поэтому я не могу экспериментировать, простите)

P.S. Что касается «Я не могу найти никакой документации об этом вообще ...» - по крайней мере, одно упоминание об этом в «официальной» документации является цитатой из книги Camel («Programming Perl», серия O'Reilly Perl), 3-е издание, глава 31.3. "использовать базу":

«Множественное наследование классов полей не поддерживается. Прагма use base вызывает исключение, если более чем один именованный базовый класс имеет поля».

person DVK    schedule 22.07.2009

Прагма полей была интересным экспериментом, но, на мой взгляд, неудачным. Самая полезная функция, проверка хеш-ключей атрибутов во время компиляции, была удалена в версии 5.10. На CPAN есть несколько приличных модулей состава классов, а также тяжеловесный, но неуклонно набирающий популярность Moose («Постмодернистская объектная система для Perl 5»).

Тем не менее, если вы хотите добавить поддержку множественного наследования, это, вероятно, будет приветствоваться; обратите внимание, что поля теперь поддерживаются независимо от perl как часть "базового" дистрибутива. Однако вам нужно заставить его работать как с реализациями на основе псевдохеша (до 5.9.0), так и с реализациями на основе ограниченного хэша (5.9.0+).

person ysth    schedule 23.07.2009