我正在写一个看起来像这样的类:
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
构建带有已定义Promises的类时,无论出于何种原因,它们在类中的属性最终都变得不确定。我该怎么做才能解决此问题?
答案 0 :(得分:7)
我应该从Liz的著作开始。将BUILD
切换为TWEAK
。然后,默认的BUILD
将执行其操作,并且套接字属性将被正确初始化。
下一个问题是&on-close
。如果您可以修改超类(在这种情况下为Tap
或Lizmat's answer to Constructors in subclases(这涉及对另一个类的属性的任何访问权),请参见Jonathan's authoritative answer to Inheriting private attributes in Perl 6,其中显示了如何处理。如果您不能修改超类,那将会很不幸。
请注意,以上两个问题实际上与使“公共属性”未定义的类中的“私有属性”无关。类型也不相关。
所有属性在技术上是私有的。私有/公共区别在于私有属性是否有公共访问器。
您的自定义BUILD
仅初始化$!VMIO
,它没有公共访问器。您忽略了初始化$!socket-host
和$!socket-port
的属性,这些属性具有具有公共访问器(由于在声明它们时使用了the public accessor twigil .
)。
您大概写了一个自定义BUILD
,因为默认的BUILD
仅用公共访问器初始化属性。但是,如果这样做,您将承担对象构建的全部责任,并且必须初始化要初始化的所有属性。
最好写一个TWEAK
。然后,您可以处理没有公共访问器的属性。 TWEAK
只是对BUILD
进行了进一步的初始化,对于默认的BUILD
,这只是对具有公共访问器的属性的初始化