perl6祝福和新的区别

时间:2016-02-26 21:52:23

标签: oop perl6 raku

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; }
}

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

my Singleton $instance = Singleton.bless; 


my Singleton $instance = Singleton.new; 

2 个答案:

答案 0 :(得分:8)

bless视为基础架构,而new是(可自定义的)界面的一部分。

如果您查看课程Mu的{​​{3}}(班级系统的根目录),您会看到bless调用nqp::create,即低级别构造函数,然后调用BUILDALL,它遍历继承链以调用相应的BUILD(子)方法来初始化对象。默认new只会调用bless

因此new调用bless来电BUILDALL来电BUILD。通常情况下,您应该单独blessBUILDALL并覆盖newBUILD进行自定义。另请注意,名称new只是一个惯例:它是一种常规方法,除了调用bless之外,它不执行任何特殊操作。

答案 1 :(得分:5)

简单来说, new 是一个功能齐全的构造函数, bless 是一个极简主义的构造函数。

引用doco on bless,祝福是......

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

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

......而新的是......

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

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

请参阅有关对象构造的文档以获取完整的故事,但关键位是;

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

在这个答案的早期版本中,我说祝福没有通过调用submethod BUILD的类层次结构 - 如上所述 - 这是错误的。 .bless 做同样的事情。

那么,你何时使用一个而不是另一个?如果类 Mu 提供的默认 .new 不是您想要的构造函数,您可以在类中声明method new,它将调用 .bless 构建对象,然后您将继续初始化属性并执行默认 .new 不执行的其他任务。