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

[email protected] (Arjan Widlak - United Knowledge) Wed, 25 Apr 2018 22:41:52 +0200
Newsgroups perl.moose
Message-ID <[email protected]>
--------------C4960976F04D5A0AF2BE61D8
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

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

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 
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.

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.)

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.



On 25/04/18 19:54, Karen Etheridge wrote:
> I'm not sure you mean by create a subclass instance on creation of its 
> superclass. Are you intending to have the superclass object have an 
> attribute that holds an instance of the subclass? Perhaps can you show 
> a diagram of what you intend your data to look like after construction 
> is complete?
>
> On Mon, Apr 23, 2018 at 7:53 AM, Arjan Widlak - United Knowledge 
> <[email protected] <mailto:[email protected]>> wrote:
>
>     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
>     <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
>
>


--------------C4960976F04D5A0AF2BE61D8
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Hi Karen,<br>
      <br>
      Thank you for your reply. Sorry if it's not clear, let me try
      again with a more concrete example. <br>
      <br>
      I have a class called Asset, with subclasses like so:<br>
      <br>
      Asset<br>
      Asset::Container<br>
      Asset::Container::KDU<br>
      <br>
      Assets are objects to be displayed, Containers are Assets, but can
      contain other Assets and Knowledge Delivery Units are a special
      kind of containers. <br>
      <br>
      I have a similar group of classes with subclasses like so:<br>
      <br>
      Response<br>
      Response::Container<br>
      <br>
      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.<br>
      <br>
      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 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. <br>
      <br>
      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.) <br>
      <br>
      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. <br>
      <br>
      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? <br>
      <br>
      Kind regards,<br>
      Arjan.<br>
      <br>
      <br>
      <br>
      On 25/04/18 19:54, Karen Etheridge wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAPJsHfAGoPRiW+aLSs3Hn8u534SWz0Uwzvb+smi0Cze+xXhtdQ@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_default" style="font-size:small">I'm not sure
          you mean by create a subclass instance on creation of its
          superclass. Are you intending to have the superclass object
          have an attribute that holds an instance of the subclass? 
          Perhaps can you show a diagram of what you intend your data to
          look like after construction is complete?<br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Mon, Apr 23, 2018 at 7:53 AM, Arjan
          Widlak - United Knowledge <span dir="ltr">&lt;<a
              href="mailto:[email protected]" target="_blank"
              moz-do-not-send="true">[email protected]</a>&gt;</span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
            <br>
            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:<br>
            <br>
            <a
href="http://search.cpan.org/dist/Moose/lib/Moose/Manual/Construction.pod#BUILD_and_parent_classes"
              rel="noreferrer" target="_blank" moz-do-not-send="true">http://search.cpan.org/dist/Mo<wbr>ose/lib/Moose/Manual/Construct<wbr>ion.pod#BUILD_and_parent_<wbr>classes</a><br>
            <br>
            BUILD methods are called from parent to child and hence this
            triggers a loop.<br>
            <br>
            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.<br>
            <br>
            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?<br>
            <br>
            Kind regards,<br>
            <br>
            Arjan<br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>

--------------C4960976F04D5A0AF2BE61D8--