Закрытый атрибут в классе делает типизированные открытые атрибуты неопределенными - PullRequest
0 голосов
/ 08 октября 2018

Я пишу класс, который выглядит следующим образом:

class ListenSocket is Tap {
    has         $!VMIO;
    has Promise $.socket-host;
    has Promise $.socket-port;

    method new(&on-close, Mu :$VMIO, Promise :$socket-host, Promise :$socket-port) {
        self.bless: :&on-close, :$VMIO, :$socket-host, :$socket-port;
    }

    submethod BUILD(Mu :$!VMIO) { }
}

Когда я пытаюсь создать класс с определенными Обещаниями для $socket-host и $socket-port, их атрибуты в классе становятсянеопределенный по любой причине.Что я могу сделать, чтобы это исправить?

1 Ответ

0 голосов
/ 08 октября 2018

Я должен был начать с того, что написала Лиз.Переключите BUILD на TWEAK.Тогда по умолчанию BUILD сделает свое дело и ваши атрибуты сокета будут правильно инициализированы.

Следующая проблема - &on-close.См. ответ Лизмата на Конструкторы в подклассах , показывающий, как с этим справиться, если вы можете изменить суперкласс (Tap в этом случае) или авторитетный ответ Джонатана на Наследование закрытых атрибутов в Perl 6 (что касается любого доступа к атрибутам другого класса), показывающее, что вам не повезло, если вы не можете изменить суперкласс.


Обратите внимание, что две вышеупомянутые проблемы на самом деле не касаются «частных атрибутов» в классе, делающем «открытые атрибуты» неопределенными.Также не имеют значения типы.

Все атрибуты технически являются частными.Различие между частным и общедоступным заключается в том, есть ли открытый аксессор для частного атрибута.

Ваш пользовательский BUILD только инициализирует $!VMIO, тот, у которого нет открытогосбруя.Вы пренебрегали инициализацией $!socket-host и $!socket-port - атрибутов, которые делают имеют общедоступные средства доступа (из-за использования общедоступного twigil . при их объявлении).

Вы предположительно написали пользовательский BUILD, потому что по умолчанию BUILD только инициализирует атрибуты с открытыми средствами доступа.Но если вы делаете это, вы берете на себя полную ответственность за построение объекта, и вы должны инициализировать все атрибуты, которые хотите инициализировать.

Лучше написать TWEAK.Тогда вы можете просто иметь дело с атрибутами без открытых методов доступа.A TWEAK just добавляет дальнейшую инициализацию к BUILD, которая по умолчанию BUILD является просто инициализацией атрибутов с общедоступными средствами доступа.

...