Jan Ingvoldstad wrote:
On Thu, Aug 20, 2009 at 10:44 PM, Kevan Benson <kben...@a-1networks.com>wrote:
That said, I submit that it's a very confusing part of the language as
defined currently, and I haven't seen a very thorough explanation of the
purpose of each method in the chain the instantiates a new object. S12
touches upon them slightly, but not in enough detail that I was able to work
out where I should be adding code to appropriately make alternate
constructors.
Now that you apparently understand it, do you have a suggestion on how S12
might be phrased differently?
I must admit that I don't quite grasp the concepts here yet, so an alternate
wording might help others as well.
Thanks for bringing the question up.
Unfortunately I'm not at all confident I do understand it all, but I'll
explain how I think it works and people more knowledgeable than me will
hopefully step in and explain where I'm wrong. Maybe out of this we can
get some consensus on what needs to be added WRT object constructors in S12.
The creation sequence looks something like this:
.new(args) {
my $self = .bless(class, {
.BUILDALL(class, args) {
# in reverse MRO
for (@parent) { .BUILD(class, args) }
.BUILD(class, args)
}
}
Note: Actually, I believe the current .BUILD is actually called as part
of the call to all parent .BUILD methods in Rakudo. At least that's
what I'm able to infer from the parrot code for Rakudo objects at
src/classes/Object.pir starting at line 272 (thanks japhb!).
.new - Handles the actual call to .new from code, define other
submethods/methods for this if you want to create alternate
constructors. You should normalize all paramaters to named values
before calling .bless. S12 implies that any .new you write (or a
constructor of any other name you define) must call .bless.
.bless - See S12
(http://perlcabal.org/syn/S12.html#Construction_and_Initialization) for
more info, but this is responsible for actually creating the object
(unless .CREATE called before and opaque object passed) and calling the
BUILD routines.
.BUILDALL - If it's still valid, http://dev.perl.org/perl6/rfc/189.html
seems to cover the expected behavior of this.
.BUILD - Used for object initialization, assigning passed named values
(pairs) to object attributes if they match, or doing something more
complex to initialize the object correctly based on supplied data.
Some things to be wary of or that I'm still hazy on:
What sort of calling syntax can be used in .new since the object isn't
yet blessed? Or since .new encapsulates .bless (right?), I guess you
can call normally AFTER the bless.
.new happens before calling parent constructors, .BUILD happens after,
so .new possibly won't have access to some default attributes as defined
by parent classes/roles.
Theoretically you could define a custom constructor, normalize data,
call the regular .new constructor, and post process on the object
returned before returning it yourself, I think.
--
-Kevan Benson
-A-1 Networks