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; }
}
I find the above code which implement Singlelton , I am wondering what the difference between bless and new in Perl6 ?
my Singleton $instance = Singleton.bless;
my Singleton $instance = Singleton.new;
Think of bless
as infrastructure, whereas new
is part of the (customizable) interface.
If you look at the implementation of class Mu
(the root of the class system), you'll see that bless
calls nqp::create
, the low-level constructor, and then invokes BUILDALL
, which walks the inheritance chain to invoke the appropriate BUILD
(sub)methods to initialize the object. The default new
in turn just calls bless
.
So new
calls bless
calls BUILDALL
calls BUILD
. Normally, you should leave bless
and BUILDALL
alone and override new
and BUILD
for customization. Also note that the name new
is just a convention: It's a regular method that doesn't do anything special besides calling bless
.
In simple terms, new is a full featured constructor and bless is a minimalist constructor.
To quote the doco on bless, bless is a ...
Lower-level object construction method than new. Creates a new object of the same type as the invocant, uses the named arguments to initialize attributes, and returns the created object. You can use this method when writing custom constructors:
class Point {
has $.x;
has $.y;
multi method new($x, $y) {
self.bless(:$x, :$y);
}
}
my $p = Point.new(-1, 1);
... whereas new is a ...
Default method for constructing (create + initialize) new objects of a class. This method expects only named arguments which are then used to initialize attributes with accessors of the same name. Classes may provide their own new method to override this default.
New triggers an object construction mechanism that calls submethods named BUILD in each class of an inheritance hierarchy, if they exist. See the docmentation on object construction for more information.
See that documentation on object construction to get the full story, but the critical bit is;
Mu.new calls method bless on its invocant, passing all the named arguments. bless creates the new object and then calls method BUILDALL on it. BUILDALL walks all subclasses in reverse method resolution order (i.e. from Mu to most derived classes) and in each class checks for existence of a method named BUILD. If it exists, it is called, again passing all named arguments from method new to it.
In an earlier version of this answer, I stated that bless doesn't go through the class hierarchy calling submethod BUILD as described above - that was false. .bless does the same thing.
So, when do you use one over the other? If the default .new supplied by class Mu is not the constructor you want, you would declare a method new
in your class which would call .bless to construct the object and then you would proceed to initialize attributes and perform those other tasks that the default .new doesn't do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With