Understanding dynamic descriptions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Understanding dynamic descriptions

Iwan Vosloo
Hi,

Can someone perhaps explain what is meant by descriptions being dynamic
in Magritte 3? I see some references to this change on the web, but do
not fully understand it. From what I understand Magritte 2 used to cache
them somewhere, and this is not done anymore. I'd like to know where
this caching used to be done and what is now different as a result in
Magritte 3.


Thanks
-Iwan


--
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

NorbertHartl

> Am 05.08.2015 um 09:15 schrieb Iwan Vosloo <[hidden email]>:
>
> Hi,
>
> Can someone perhaps explain what is meant by descriptions being dynamic in Magritte 3? I see some references to this change on the web, but do not fully understand it. From what I understand Magritte 2 used to cache them somewhere, and this is not done anymore. I'd like to know where this caching used to be done and what is now different as a result in Magritte 3.
>
In Magritte 2 descriptions are on the class side. So they are the same for every instance of that class. If I remember correctly the MAPragmaBuilder built and cached the descriptions for a class. In Magritte 3 the descriptions moved to instance side. This enables the powers of having descriptions individually for a single instance but it makes caching a task that is not possible. A single description can be different over time when an instance changes state etc.

Hope this helps,

Norbert


_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
On 05/08/2015 10:38, Norbert Hartl wrote:
>
>> Am 05.08.2015 um 09:15 schrieb Iwan Vosloo <[hidden email]>:
>>
>> Hi,
>>
>> Can someone perhaps explain what is meant by descriptions being dynamic in Magritte 3? I see some references to this change on the web, but do not fully understand it. From what I understand Magritte 2 used to cache them somewhere, and this is not done anymore. I'd like to know where this caching used to be done and what is now different as a result in Magritte 3.
>>
> In Magritte 2 descriptions are on the class side. So they are the same for every instance of that class. If I remember correctly the MAPragmaBuilder built and cached the descriptions for a class. In Magritte 3 the descriptions moved to instance side. This enables the powers of having descriptions individually for a single instance but it makes caching a task that is not possible. A single description can be different over time when an instance changes state etc.
>

Thanks, Norbert. I get that, but when you do, for example:

aComponent := anObject asComponent.

then aComponent holds onto the description created above (in
asComponent's implementation), as I understand it.
This means that as long as aComponent exists, it will always refer to
the same description.

Is that understanding correct?

Thanks
- Iwan

--
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

NorbertHartl

Am 05.08.2015 um 10:58 schrieb Iwan Vosloo <[hidden email]>:

On 05/08/2015 10:38, Norbert Hartl wrote:

Am 05.08.2015 um 09:15 schrieb Iwan Vosloo <[hidden email]>:

Hi,

Can someone perhaps explain what is meant by descriptions being dynamic in Magritte 3? I see some references to this change on the web, but do not fully understand it. From what I understand Magritte 2 used to cache them somewhere, and this is not done anymore. I'd like to know where this caching used to be done and what is now different as a result in Magritte 3.

In Magritte 2 descriptions are on the class side. So they are the same for every instance of that class. If I remember correctly the MAPragmaBuilder built and cached the descriptions for a class. In Magritte 3 the descriptions moved to instance side. This enables the powers of having descriptions individually for a single instance but it makes caching a task that is not possible. A single description can be different over time when an instance changes state etc.


Thanks, Norbert. I get that, but when you do, for example:

aComponent := anObject asComponent.

then aComponent holds onto the description created above (in asComponent's implementation), as I understand it.
This means that as long as aComponent exists, it will always refer to the same description.

Is that understanding correct?

I think that is correct. I don't use magritte much lately so my memory is slightly blurry. I need to give a more precise answer to the instance side description. A description can alter in two ways. Either the shape/class of the description changes when accessed multiple times. I think this is a not so likely thing to happen. The other way would be if the data in the description changes because the object changed. So a multiple option description can update the list of options while the descriptions stay the same. And that is one thing you gain with Magritte3 because you can have descriptions with dynamic data that has access to the instance.

Norbert



_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
On 05/08/2015 11:14, Norbert Hartl wrote:

Am 05.08.2015 um 10:58 schrieb Iwan Vosloo <[hidden email]>:

Thanks, Norbert. I get that, but when you do, for example:

aComponent := anObject asComponent.

then aComponent holds onto the description created above (in asComponent's implementation), as I understand it.
This means that as long as aComponent exists, it will always refer to the same description.

Is that understanding correct?

I think that is correct. I don't use magritte much lately so my memory is slightly blurry. I need to give a more precise answer to the instance side description. A description can alter in two ways. Either the shape/class of the description changes when accessed multiple times. I think this is a not so likely thing to happen. The other way would be if the data in the description changes because the object changed. So a multiple option description can update the list of options while the descriptions stay the same. And that is one thing you gain with Magritte3 because you can have descriptions with dynamic data that has access to the instance.


Thanks Norbert, I have to ask stupid questions because I realise I am sometimes struggling for lack of understanding some fundamental concepts.

I think I understand how some of the data displayed by a component can change during the lifetime of the component. For example, a MAElementDescriptionComponent>>value will just use the accessor set on the description, so that is quite dynamic. But what I am struggling with is things like setting visibility of a description. For example I could have the following on the instance side of my object:

descriptionNumber
  ^ MANumberDescription new
         selectorAccessor: #number;
         visible: self mayBeSeen;
         yourself

... with the assumption that mayBeSeen is a method on my object that might return a different result during the lifetime of aComponent in my example above.


But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description. The description in turn lives as long as the MAContainerComponent stays alive. So, I don't really understand how one can change the contents of the MAContainerComponent based on something like visible: on the description.  (I thought magritteDynamicObject could help here, but magritteDynamicObject is deprecated in Magritte3.)



Regards
- Iwan

-- 
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

NorbertHartl

Am 05.08.2015 um 11:42 schrieb Iwan Vosloo <[hidden email]>:

On 05/08/2015 11:14, Norbert Hartl wrote:

Am 05.08.2015 um 10:58 schrieb Iwan Vosloo <[hidden email]>:

Thanks, Norbert. I get that, but when you do, for example:

aComponent := anObject asComponent.

then aComponent holds onto the description created above (in asComponent's implementation), as I understand it.
This means that as long as aComponent exists, it will always refer to the same description.

Is that understanding correct?

I think that is correct. I don't use magritte much lately so my memory is slightly blurry. I need to give a more precise answer to the instance side description. A description can alter in two ways. Either the shape/class of the description changes when accessed multiple times. I think this is a not so likely thing to happen. The other way would be if the data in the description changes because the object changed. So a multiple option description can update the list of options while the descriptions stay the same. And that is one thing you gain with Magritte3 because you can have descriptions with dynamic data that has access to the instance.


Thanks Norbert, I have to ask stupid questions because I realise I am sometimes struggling for lack of understanding some fundamental concepts.

These are no stupid questions. Just go ahead. The only thing that can happen is that we all learn something.

I think I understand how some of the data displayed by a component can change during the lifetime of the component. For example, a MAElementDescriptionComponent>>value will just use the accessor set on the description, so that is quite dynamic. But what I am struggling with is things like setting visibility of a description. For example I could have the following on the instance side of my object:

descriptionNumber
  ^ MANumberDescription new
         selectorAccessor: #number;
         visible: self mayBeSeen;
         yourself

... with the assumption that mayBeSeen is a method on my object that might return a different result during the lifetime of aComponent in my example above.


But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description. The description in turn lives as long as the MAContainerComponent stays alive. So, I don't really understand how one can change the contents of the MAContainerComponent based on something like visible: on the description.  (I thought magritteDynamicObject could help here, but magritteDynamicObject is deprecated in Magritte3.)

I'm not sure I can give a good answer to this. And I'm not sure it is a feasible use case to have visibility fully dynamic. Usually you create a component and the visibility of the elements should be defined by then. 
Moving stuff to the instance side opened the possibility to have more dynamic stuff that can access the instance but there is surely a lack of support for things like the one you describe. So not everything can be used dynamically. We need to decide which of these things need to be integrated into magritte.

Can you describe a more detailled use case why you would want to have dynamic visibility of elements?  

Norbert



_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Stephan Eggermont-3
In reply to this post by Iwan Vosloo


Verstuurd vanaf mijn iPhone

> Op 5 aug. 2015 om 11:42 heeft Iwan Vosloo <[hidden email]> het volgende geschreven:
>
> But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description.

Normally the evaluation happens at component creation time. You can however use a builder that evaluates at other points in time. The component has a reference to the description so everything you need is there. You just need a smarter builder and/or component

Stephan
_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
In reply to this post by NorbertHartl
On 05/08/2015 11:53, Norbert Hartl wrote:

Am 05.08.2015 um 11:42 schrieb Iwan Vosloo <[hidden email]>:

But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description. The description in turn lives as long as the MAContainerComponent stays alive. So, I don't really understand how one can change the contents of the MAContainerComponent based on something like visible: on the description.  (I thought magritteDynamicObject could help here, but magritteDynamicObject is deprecated in Magritte3.)

I'm not sure I can give a good answer to this. And I'm not sure it is a feasible use case to have visibility fully dynamic. Usually you create a component and the visibility of the elements should be defined by then. 
Moving stuff to the instance side opened the possibility to have more dynamic stuff that can access the instance but there is surely a lack of support for things like the one you describe. So not everything can be used dynamically. We need to decide which of these things need to be integrated into magritte.

Can you describe a more detailled use case why you would want to have dynamic visibility of elements?  


I appreciate the discussion Norbert.

The system I'm working on is big and a real example is difficult to provide due to all the context needed, but here is a simplified example based on something real:

Assume I have a Transaction object which a user can match to a Payment. There's a screen on which the user can edit the Transaction. On this screen there is a button the user can click in order to choose a Payment to match it to.

To keep the example simple, I am ignoring the Payment and the bits about choosing it. Instead the Transaction edit screen just has a "Match" button that the user can click to mark the Transaction as being matched. The expectation is that the user will stay on the same screen (thus same component), doing other stuff after such matching.

When the user first sees the Transaction screen, it displays all sorts of contents of the Transaction, but nothing about what it is matched to (because it is not matched at this time). Once matched, in the simplified example, it should include a readonly item stating when it was matched.  (In the real world, this could be an MAToOneRelationDescription that renders as a link to the Payment that was matched, and that displays only if there was indeed a Payment matched.)

So I'd have something like:

A class Transaction with instVar 'matchedTime' and:

Transaction>>descriptionMatchedTime
    <magritteDescription>
    ^ MADateAndTimeDescription new
          selectorAccessor: #matchedTime;
          readonly: true;
          visible: self isMatched;
          label: 'Matched at';
          yourself.

... and somewhere else I'll create the component to be displayed like this:

myComponent:= aTransaction asComponent
       addValidatedForm: { [:theTransaction| theTransaction match] -> 'Match' };
       yourself


With this code the matched time is never displayed, since the Boolean passed to visible: is evaluated only when the MAContainerComponent is created.

Regards
- Iwan


-- 
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
In reply to this post by Stephan Eggermont-3
On 05/08/2015 13:13, Stephan Eggermont wrote:
>
>> Op 5 aug. 2015 om 11:42 heeft Iwan Vosloo <[hidden email]> het volgende geschreven:
>>
>> But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description.
> Normally the evaluation happens at component creation time. You can however use a builder that evaluates at other points in time. The component has a reference to the description so everything you need is there. You just need a smarter builder and/or component
>

Hi Stephan,

That sounds promising. Where can I read more about this? What is the
builder for, is it for the description or for the component?

Regards
- Iwan


--
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
On 05/08/2015 14:35, Iwan Vosloo wrote:

> On 05/08/2015 13:13, Stephan Eggermont wrote:
>>
>>> Op 5 aug. 2015 om 11:42 heeft Iwan Vosloo <[hidden email]> het
>>> volgende geschreven:
>>>
>>> But it seems that visible: can only take a Boolean, which the
>>> description then retains for the lifetime of the description.
>> Normally the evaluation happens at component creation time. You can
>> however use a builder that evaluates at other points in time. The
>> component has a reference to the description so everything you need
>> is there. You just need a smarter builder and/or component
>>
>

I have looked at this a bit more... but still have no clue as to how to
do this. I get lost somewhere between MAPRagmaBuilder and the fact that
a MAContainerComponent creates its children components when it get
initialised - all on top of a set of related Descriptions that can never
be replaced by others.

Wouldn't it be simpler to just change visible: to be able to take a
block similar to addCondition: and always evaluate that block when
isVisible is called (for example)? This can be done consistently for a
bunch of other things too, like isReadonly, isRequired etc.

Regards
- Iwan

--
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Sean P. DeNigris
Administrator
Iwan Vosloo wrote
a MAContainerComponent creates its children components when it get
initialised - all on top of a set of related Descriptions that can never
be replaced by others.

Wouldn't it be simpler to just change visible: to be able to take a
block...
You've hit a limitation of Magritte - forms are fairly static. A "view" is pretty much just a read-only form. Even when you edit the object, you're usually editing a cached Memento, not the object itself. I've sometimes thought about an MAUpdatingMemento, but unless the object is designed for this (e.g. sends announcements) you'd have to use polling.

Anyway, the upshot is that #visible: doesn't take a block because Magritte's design freezes forms in time. If you want to do things a different way, it will take more than a block (which would still only be evaluated once), but a rethinking of the infrastructure. Of course, this being Smalltalk, why not!
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

NorbertHartl
In reply to this post by Iwan Vosloo

Am 17.08.2015 um 11:29 schrieb Iwan Vosloo <[hidden email]>:

On 05/08/2015 14:35, Iwan Vosloo wrote:
On 05/08/2015 13:13, Stephan Eggermont wrote:

Op 5 aug. 2015 om 11:42 heeft Iwan Vosloo <[hidden email]> het volgende geschreven:

But it seems that visible: can only take a Boolean, which the description then retains for the lifetime of the description.
Normally the evaluation happens at component creation time. You can however use a builder that evaluates at other points in time. The component has a reference to the description so everything you need is there. You just need a smarter builder and/or component



I have looked at this a bit more... but still have no clue as to how to do this. I get lost somewhere between MAPRagmaBuilder and the fact that a MAContainerComponent creates its children components when it get initialised - all on top of a set of related Descriptions that can never be replaced by others.

I'm not sure replacement of the child descriptions is the right way to take it. You are building a form at a specific point in time. The view you will see an the screen reflects that. The relationship between uncommitted data in your form and the change in the structure of the view is not obvious. If you want to have the UI reflect a behaviour in visibility the best way might be to recognize the change in that boolean and to recreate/replace the view with a new one. This way you could track the side effects of changing a single value as well. If you want to keep uncommited data there might be a possibility to recreate the view but make it use the current memento. Without dedicated and specified use case it is hard to tell if there is a good way to do it or if there are shortcomings in magritte.

Wouldn't it be simpler to just change visible: to be able to take a block similar to addCondition: and always evaluate that block when isVisible is called (for example)? This can be done consistently for a bunch of other things too, like isReadonly, isRequired etc.

If you take your single use case it might seem feasible. But what if have components that are hidden if another one is visible and vice versa. The interdependencies can be really complex. From this point of view recreating the whole thing (as described above) might be the best way to do.

Norbert

Regards
- Iwan

-- 
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki


_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki
Reply | Threaded
Open this post in threaded view
|

Re: Understanding dynamic descriptions

Iwan Vosloo
In reply to this post by Sean P. DeNigris
On 17/08/2015 13:20, Sean P. DeNigris wrote:
> Anyway, the upshot is that #visible: doesn't take a block because Magritte's
> design freezes forms in time.

On 17/08/2015 13:46, Norbert Hartl wrote:
> You are building a form at a specific point in time. The view you will
> see an the screen reflects that. [...] If you want to have the UI
> reflect a behaviour in visibility the best way might be to recognize
> the change in that boolean and to recreate/replace the view with a new
> one.

Thanks. That is an important thing for me to understand. Coming from
other technologies the single thing that stands out the most about
Seaside is that components are stateful, and stick around for multiple
requests. From what you are saying Magritte goes a bit against that
notion, and that for the use case I presented "the magritte way" is to
recreate the component tree instead of keeping it around.


> The relationship between uncommitted data in your form and the change
> in the structure of the view is not obvious.

I was actually not referring to uncommitted data. I am thinking of a
scenario where you are on one page, click on a button which executes a
callback in which everything validates properly, and the mementos are
committed before also effecting some changes in the domain.

But, the user stays on the same page (and thus also component) after
having clicked on this button. So, the same component is displayed again
- but some of its elements that were previously not visible now also
appear. I actually really thought this is something many people would
need to build on their user interfaces.

>   If you want to do things a different way, it
> will take more than a block (which would still only be evaluated once), but
> a rethinking of the infrastructure. Of course, this being Smalltalk, why
> not!

I'd like to explore how possible this is... We already have
modifications of Magritte where we pass in a block that is evaluated
each time isVisible is called. What else would need to change? What I
know is that MAContainerComponent creates its children components upon
construction and it only creates the visible ones. I suppose one would
need to be able to refresh it somehow after a callback so that it can
update its children to include new ones that have become visible. Or
perhaps it should create all child components initially regardless of
whether they are visible or not - and only selectively render them based
on visibility.  Similarly validation should probably only be propagated
to visible children.

This assumes that the child MADescriptions of the MAContainer on which
the MAContainerComponent is based do not ALSO change as a result of the
changed domain, which is not a bad assumption in my view.

Am I naive to think that it is not really much more complicated than that?

> Without dedicated and specified use case it is hard to tell if there
> is a good way to do it or if there are shortcomings in magritte.

I'd happily improve the specification of my little use case if you can
point out where I am vague? I will also happily post experimental code
people can play with. We are grateful if anyone wants to participate/guide!

Regards
- Iwan

--
Reahl, the Python only web framework: http://www.reahl.org

_______________________________________________
Magritte, Pier and Related Tools ...
https://www.iam.unibe.ch/mailman/listinfo/smallwiki