Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BUILD and how to create a subclass object when creating a parent

3 views
Skip to first unread message

Arjan Widlak - United Knowledge

unread,
Apr 23, 2018, 11:30:03 AM4/23/18
to mo...@perl.org
Hi,

I tried to use the BUILD method to create an instance of a subclass on
creating an instance of the parent. This does not work and the
documentation clearly explains why:

http://search.cpan.org/dist/Moose/lib/Moose/Manual/Construction.pod#BUILD_and_parent_classes

BUILD methods are called from parent to child and hence this triggers a
loop.

I am able to do this with the around method modifier, however I need to
override the behaviour in the subclass. This is also seems error prone
and bad practice.

But if this cannot be done this way, how should it be done? How can I
always create a subclass instance on creation of it's superclass?

Kind regards,

Arjan

Arjan Widlak - United Knowledge

unread,
Apr 26, 2018, 6:45:02 AM4/26/18
to Marco Silva, Karen Etheridge, Moose List
Dear Marco,

Thanks for your reply. Discussion on what containers might be, is not
what I'm looking for. The question is about Moose and how it could and
could be used. Formulated less open than before: is there an option for
an execution order that is the inverse of Method modifiers?

Your final advise might be sound though, if the answer is no.

Kind regards,
Arjan.

On 25/04/18 23:07, Marco Silva wrote:
> Excerpts from Arjan Widlak - United Knowledge's message of 2018-04-25 22:41:52 +0200:
>> Hi Karen,
>>
>> Thank you for your reply. Sorry if it's not clear, let me try again with
>> a more concrete example.
>>
>> I have a class called Asset, with subclasses like so:
>>
>> Asset
>> Asset::Container
>> Asset::Container::KDU
>>
>> Assets are objects to be displayed, Containers are Assets, but can
>> contain other Assets and Knowledge Delivery Units are a special kind of
>> containers.
>>
>> I have a similar group of classes with subclasses like so:
>>
>> Response
>> Response::Container
> Container idea is generally a list (a data structured to hold the type
> you are holding). Anything different than that is just simply confusing
> and should be avoided.
>
>> A Response is some response on an Asset by a user. The
>> Response::Container subclass sees if all Assets in a Container have
>> received a Response. It's like a summary of it's parent class.
>>
>> Now the problem. If I create a Response, I might like to create a
>> Response::Container instance as well. If the Response I am about to
> Why not simple add the Response to the container ?
> my $r = Response->new;
> $container->add($r);
>
>> create is the last Response needed for all Assets in the Container to
>> have received a Response, than I would like to create a
>> Response::Container subclass instance.
> Makes no sense.
>
>> So creation of an instance of a subclass - Response::Container - is only
>> dependent on the creation of the parent class - Response. Therefore it
>> seems like a good design choice to couple this to the create method of
>> Response. (Where the create method does new, update the database, and
>> new_by_id, to re-instantiate from the database.)
> Again, you don't create a new instance for container otherwise is not
> containing more then one item inside.
>
>> How does the Moose framework envision such a case? I expected BUILD to
>> be the answer. It causes a deep recursion, so it's definitely not, as is
>> well documented. Around also causes a deep recursion by default if one
>> does this, that can be avoided though by creating an empty subroutine in
>> the subclass. Quite error prone, so not the obvious choice.
>>
>> Since many of the ideas in Moose - Roles, Method modifiers, etc. - are
>> design ideas, I thought there is probably a view on cases like this.
>> However I cannot find the obvious way to to couple the creation of a
>> subclass to the creation of a parent class in Moose. How would one be
>> expected to do this in Moose?
>>
>> Kind regards,
>> Arjan.
> Probably you should try another design. A simple one
>

Thomas Klausner

unread,
Apr 26, 2018, 8:00:02 AM4/26/18
to Moose List, Arjan Widlak - United Knowledge
Hi!

On Thu, Apr 26, 2018 at 07:45:58AM -0400, Chris Prather wrote:

> > Thanks for your reply. Discussion on what containers might be, is not what I'm looking for. The question is about Moose and how it could and could be used. Formulated less open than before: is there an option for an execution order that is the inverse of Method modifiers?
> >
> > Your final advise might be sound though, if the answer is no.
> >
>
> Look at augment/inner but experience says that if you’re reaching for this you need to rethink your design because you’re over coupling something somewhere.

And while it might be possible to coerce Moose to do what you want
automagically, I think it makes for much better / easier to
understand code if you "just" create some methods that explictly do what
you need. That way your future self can just read what's happening
without having to hunt through several layers of Moose magic...

Greetings,
domm

--
#!/usr/bin/perl http://domm.plix.at
for(ref bless{},just'another'perl'hacker){s-:+-$"-g&&print$_.$/}

Arjan Widlak - United Knowledge

unread,
Apr 26, 2018, 11:30:03 AM4/26/18
to Thomas Klausner, Moose List
Thanks all. I got it to work, but yes, I'm going to rethink the design anyway.

For those who are interested in how it can be done:

      Asset::Container::KDU1        Response1        Response::Summary1
Del-> 
Asset::Container::KDU2 (6)    Response2 (5)    Response::Summary2 (4)
       
Asset::Container::KDU3 (3)    Response3 (2)    Response::Summary3 (1)

Cascading a delete from (1) to (6) with a delete method on (6) works with:
- A 'before delete' in Asset::Container, that iterates through it's direct children in the lineage.
- A 'before delete' in Asset, that iterates through it's own Responses.
- And finally a 'before delete' in Response that iterates through the Summaries.

But true, this is too complex. And so would Inner and Augment be. Not transparent enough.

Thanks for the feedback!

Kind regards,
Arjan.



On 26/04/18 13:52, Thomas Klausner wrote:
0 new messages