Oop 祝福和新的区别

Oop 祝福和新的区别,oop,raku,Oop,Raku,我发现上面的代码实现了Singlelton,我想知道在Perl6中bless和new的区别是什么 class Singleton { # We create a lexical variable in the class block that holds our single instance. my Singleton $instance = Singleton.bless; # You can add initialization arguments here. me

我发现上面的代码实现了Singlelton,我想知道在Perl6中bless和new的区别是什么

class Singleton {
    # We create a lexical variable in the class block that holds our single instance.
    my Singleton $instance = Singleton.bless; # You can add initialization arguments here.
    method new {!!!} # Singleton.new dies.
    method instance { $instance; }
}

简单地说,new是一个功能齐全的构造器,bless是一个极简构造器

引用这句话,祝福是一个

较低级别的对象构造方法。 创建与发票类型相同的新对象,使用命名参数初始化属性,并返回创建的对象。 编写自定义构造函数时可以使用此方法:

。。。而new是一个

用于构造(创建+初始化)类的新对象的默认方法。此方法只需要命名参数,然后使用这些参数初始化具有相同名称的访问器的属性。类可以提供自己的新方法来覆盖此默认值

New触发对象构造机制,该机制在继承层次结构的每个类中调用名为BUILD的子方法(如果存在)。有关更多信息,请参阅。

请参阅有关对象构造的文档以了解完整情况,但关键是:

new在其invocant上调用方法bless,传递所有命名参数。bless创建新对象,然后对其调用方法BUILDALL。BUILDALL以相反的方法解析顺序(即从Mu到大多数派生类)遍历所有子类,并在每个类中检查名为BUILD的方法是否存在。如果它存在,则调用它,再次将所有命名参数从新方法传递给它

在这个答案的早期版本中,我指出bless没有像上面描述的那样通过类层次结构调用submethod BUILD——这是错误的。祝福也做同样的事情


那么,你什么时候用一个来代替另一个呢?如果classMu提供的默认.new不是您想要的构造函数,您将在类中声明一个
方法new
,该方法将调用.bless来构造对象,然后您将继续初始化属性并执行默认.new不执行的其他任务。

bless
视为基础结构,而
new
是(可定制)界面的一部分

如果您查看类
Mu
(类系统的根),您将看到
bless
调用底层构造函数
nqp::create
,然后调用
BUILDALL
,它遍历继承链调用适当的
BUILD
(sub)方法来初始化对象。默认的
new
依次调用
bless


所以
new
调用
bless
调用
BUILDALL
调用
BUILD
。通常,您应该将
bless
BUILDALL
单独保留,并覆盖
new
BUILD
进行自定义。还要注意的是,名称
new
只是一个约定:它是一个常规方法,除了调用
bless

之外,没有任何特殊功能,我认为“精华”是不对的;“按照正确的顺序初始化属于父类的任何属性”实际上就是bless所做的。默认的“new”方法除了使用它传递的所有命名参数调用bless之外,什么都不做。经过实验,您是对的。非常感谢你指出这一点——这对我来说是一个重大的“错误导向”。我会更新我的答案。
my Singleton $instance = Singleton.bless; 


my Singleton $instance = Singleton.new; 
class Point {
    has $.x;
    has $.y;
    multi method new($x, $y) {
        self.bless(:$x, :$y);
    }
}
my $p = Point.new(-1, 1);