yary wrote:

>>The current approach is violating the DRY principle. When you write a
>>.new method that wants to initialize private attributes, you have to
>>repeat all their names again in the signature of your BUILD submethod:

The other way of looking at this is that redefining the new() is about
changing the constructor interface, whereas defining the BUILD() is
about changing the initialization behaviour.

So the current approach is violating DRY in order to preserve the more
important principle of Separation of Concerns. After all, it doesn't seem
unreasonable that, if you want to modify two behaviours, you have to
rewrite two components to do it.

On the other hand, rather than adding a blessall() alternative,
perhaps we could say that, if the class explicitly redefines new(), then
any call to bless() within that redefined new() will accept both public
and private attributes for auto-initialization...under the theory that,
by redefining new() the class implementor is taking direct
responsibility for the construction...and is willing to live with the
dire consequences if they mess it up.

Incidentally, blessall() seems a dubious name to me, given that we
already have BUILDALL() and CREATEALL(), where the '-ALL' suffix means
something quite different from what the '-all' would mean at the end of
blessall().

Better still, on the principle that abnormal behaviour should always be
explicitly marked and lexically predeclared, perhaps a pragma would
be appropriate:

    class A {
        has ($!x, $!y, $!z);

        method new($x, $y, $z) {
            no strict :autoinit;
            self.bless(*, :$x, :$y, :$z)
        }
    }


>>The whole point of having BUILD() is to separate allocation
>> concerns from initialization concerns.
>
> Here's where I am late to the conversation, I hadn't known that
> distinction. S12 doesn't talk about the "why" of BUILD/BUILDALL, at
> least not that detail. If "BUILD" is for allocation, and "new" is for
> initialization, then hiding private attributes from "bless" is forcing
> the programmer to use BUILD for initialization which wasn't the
> intent.

You have it the wrong way round: new() is for allocation; BUILD() is for
initialization. From a design point-of-view, BUILD() probably should
have been called INIT(), but that keyword was already taken.


> "you must write your own BUILD (as above) in order to present private
> attributes as part of your initialization API."
>
> And that's not so good, because it forces BUILD to be used for
> initialization,

...which is precisely what it's supposed to be for. :-)

Damian

Reply via email to