类中的私有属性使得类型化的公共属性未定义

Kai*_*epi 8 perl6

我正在写一个看起来像这样的课程:

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) { }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试构建类与定义的承诺$socket-host$socket-port,其在类属性最终成为未定义无论出于何种原因.我该怎么做才能解决这个问题?

rai*_*iph 7

我应该从Liz所写的开始.切换BUILDTWEAK.然后默认BUILD将执行它的操作,您的套接字属性将被正确初始化.

下一个问题是&on-close.如果您可以修改超类(在本例中)或Jonathan 在Perl 6中继承私有属性的权威答案(这是对任何其他类的属性的任何访问),请参阅Lizmat对子结构中的构造函数的回答,显示如何处理它.如果你不能修改超类,那就走运了.Tap


请注意,上述两个问题实际上并不是关于使"公共属性"未定义的类中的"私有属性".类型也不相关.

所有属性在技术上都是私有的.私有/公共区别在于是否存在私有属性的公共访问者.

您的自定义BUILD仅初始化$!VMIO,即没有公共访问者的自定义.你已经忽略了初始化$!socket-host$!socket-port,这些属性有公共存取(由于使用的公共访问twigil.声明它们时).

您可能会编写一个自定义,BUILD因为默认情况下BUILD只使用公共访问器初始化属性.但是,如果您这样做,则您要承担对象构造的全部责任,并且必须初始化要初始化的所有属性.

写一个更好TWEAK.然后,您可以在没有公共访问器的情况下处理属性.一TWEAK只是进一步增加了初始化BUILD,它默认BUILD是属性刚刚初始化公众存取.