有谁知道为什么TWEAK例程在BUILD例程之前被命中?

问题描述

最小代码:

 #!/usr/bin/raku

 class   Widget {
         submethod TWEAK(:$content,:$styles) {
                 say "t1\n";
         }
 }

 class   File is Widget {
         submethod BUILD() {
                 say "b1";
         }
 }

 my $xml = File.new();

输出:

 t1

 b1

相关文档位于https://docs.raku.org/language/objects#Object_construction。我引用:“在调用BUILD方法之后,将调用名为TWEAK的方法(如果存在的话),并使用传递给new的所有命名参数来进行调用。”

我正在使用Fedora 32附带的rakudo版本(rakudo-0.2020.02-1.fc32.x86_64可能是今年2月)。

解决方法

一项快速实验向缺少示例的每个示例类添加了TWEAKBUILD方法,显示调用顺序为Widget::BUILD-> Widget::TWEAK-> {{ 1}}-> File::BUILD

所以我认为问题在于文档的措辞:“在调用BUILD方法之后,将调用名为TWEAK的方法(如果存在的话),并再次将所有已命名的参数传递给new。”

我认为应该是“在为每个类调用BUILD方法后 ,如果存在,则将名为TWEAK的方法称为该类的 。传递给new的所有命名参数。”

这将记录似乎正在发生的事情。

注意:自回答此问题以来,文档已更新以反映代码的运行方式。

,

TWEAKBUILD之后被调用。

但是,子类仍然需要遵循其父类的构造例程。考虑以下代码:

class Foo {
  submethod TWEAK { say "Foo tweak" }
  submethod BUILD { say "Foo build" }
}

class Bar is Foo {
  submethod TWEAK { say "Bar tweak" }
  submethod BUILD { say "Bar build" }
}

Bar.new

如果运行它,您可以很快看到发生的事情:

Foo build
Foo tweak
Bar build
Bar tweak

基本上,每个类的构造方法都不会被调用,直到为父类调用了它们为止,这意味着在构建和调整时,您都可以假定父类的属性已正确初始化。

这实际上是那些方法需要成为子方法的原因,否则,如果父类的build方法引用了private属性,并且子类继承了Parents方法,则会收到错误消息,因为这两个方法都将被调用专利和儿童,但该儿童将无权使用。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...