Hi,
We'd like some help with how nil / undefined is handled in Magritte,
and specifically a MAStringDescription. The method MAStringReader >>
read:description: overrides the default behaviour to return nil. Is a
nil in Magritte seen as a "unpopulated" token?
Our problem more specifically is this:
We start with an object containing an string in an instance variable.
We use a MAStringDescription for this instance variable. We use the
magritte-seaside binding to edit this field on the UI. If the user
does not capture text in the text input, an empty string is "written".
The method on MAStringReader mentioned above intercepts this and
returns nil, so nil is written back to our domain object, where we
started off with an empty string.
We do not want nils to be written into our domain object where we
initialized it with an empty string.
How do we fix this? Is there a hook where we should be specifying
this? Or is there a fundamental way of working with Magritte-Seaside
where it will write nils and we have to manage that on our domain
object?
Thanks for your help.
Otto
Hi all,
The project Pier3 Addons is for some time red. Maybe I broke something in the configuration, as RSS had a wrong version number. This is actually seaside… so should be version 3.1.0.
After I fixed this: stable was green again. Development still is red, because some initialiser method that is called no longer seem to exist. Maybe someone removed this?
I also added this mailing list to be informed when the build fails.
Cheers,
Diego
I wonder why MADescription isn't a "valuable" object.
It is... it doesn't understand the #value: message selector.
#value: could map to the accessor #read: and #value:value: to the the
accessor #write:to:
Is there a reason why it isn't this way.
It would make it very useful from a polymorphic point of view.
E.g.
#size value: #(1 2 7).
[ :value | value size ] value: #(1 2 7).
(MANumberDescription new accessor: #size) value: #(1 2 7).
Regards,
Esteban A. Maringolo
Hi all,
We have been looking at ways to transfer data between Pharo and Gemstone. We decided to use Magritte-Json to export and import our model.
- Magritte-Json allows control over what to export: using the flag “isJsonSerialized”. This allows us to simply set this flag where needed.
- Magritte-Json has no loop detection. It has several ways to control what is serialized. Mainly the flags: “isJsonSerialized” and “useJsonKey"
We needed to modify old implementation
- It did not make proper use of the JsonReader and JsonWriter you could set. We have some references to other objects. From the magritte-description we know the expected type. These objects need to be serialised as keys, instead of the object itself. On materialising we need to make a lookup. We made a KeyWriter for this.
- We do better detection of what class is read. The old implementation simply took the first class from the magritte-description, but this is not always correct.
- We improved the option serialisation. On reading, when there is a possible match, we make this match.
- We improved the relation serialisation. On writing it can write a key instead of the entire object. On reading it looks the key up in the collection (ownedIn) to create the exact value.
We took a look at the following alternatives:
- Fuel. It would be great is Fuel would be available for Gemstone as well, as it is fast and the transfer file is compact. Current implementation does not load in Gemstone, because it is using primitives. The following things need to be done to make this run in Gemstone:
— Splitting Fuel up into packages, with a Pharo specific part and a general part.
— Implementing the core export functionality in Gemstone (only the methods to read/write basic types like boolean, integer, etc. need implementing).
— Mapping basic types where needed.
We decided that especially the first (splitting up Fuel) was too much effort for us, as up until now we are only users of Fuel.
- Ston. We hoped Ston would use magritte descriptions to determine what to export. It turned out to use metaprogramming and Ston does not handle loops. In order to make this work for us, we needed to rip our model to remove all back links. A better alternative would have been Sixx. Sixx is XML based and a bit larger. Also it would involve some extra packages loaded into production.
How to use Magritte-Json:
First you need to remove the loops from your model. The simple situation is when you have a tree. If this is the case, you don’t need to do anything.
If you have other references you need to decide who the primary owner is. The owner writes the object, all other references write keys. There two cases we have implemented:
- There is a parent / child relation. The parent has a number of children and each child has a reference back. In the description of the child you mark this description as “isParent: true”. This causes it no longer to be serialized by json and on deserialisation it is set to the new parent (using the parsing context)
- There is an owner. The owner holds a number of values, and this is on (or more) of it. In the description of the references objects you refer to the owner in the “isOwnedIn:”. The value method should return a collection that each value is a member of. On serialisation it writes the jsonKey (you need to implement this method). On deserialisation it looks this value up in the collection. Of this value is not found, the key is retained in the collection. Note that this is processed after the other part of model is restored. I.e. it is possible to first write articles with references to an article group, and then write the article groups the articles can belong to.
You can find some examples in the tests of what you can serialise and how to set up the Magritte descriptions accordingly. If these cases do not cover your needs you can create your own reader / writer that does this. Keep them in pairs, and you should probably inherit from the MJBasicJson-Writer / -Reader, as some of the added functionality may interfere.
If there are any questions I am of course happy to answer them. And if you find bugs, please let me know.
Cheers,
Diego
Hi all,
I'm adding some features on top of my existing Magritte metamodel
descriptions, and I found some of the features I want to add to be already
there (or so it seems, QCQuery for instance), but I don't understand them
just by looking at the code.
Does anybody have a video or something other than the Dry-Ing Magritte
slides? (http://www.slideshare.net/esug/drying-magritte)
I don't want to build what's already there or might be extended... without
exceeding my customer deadlines. :)
Regards!
--
View this message in context: http://forum.world.st/Deep-QCMagritte-tutorial-tp4744612.html
Sent from the Magritte, Pier and Related Tools mailing list archive at Nabble.com.
I know all the advantages of having the descriptions defined in the
instance side. But I find one drawback.
Let's suppose I want to implement a tool that works at meta level, and
I want a list of the available descriptions of a class in order to
build a query where each description will map to a column.
Is there any way I can obtain all the instance side descriptors
without having to instantiate my object?
MyModel has
#descriptionA
#descriptionB
#descriptionC
I want something like: MyModel>>#magritteDescriptionOfInstances and
get the above mentioned descriptions.
I know some descriptions will need specific instance variables in
order to work, I would like also to categorize/filter those
descriptions that are "class side friendly" (it is, they don't require
instance specific behavior).
Otherwise I don't see other option than to partition the descriptors
to both instance and class side.
E.g.:
MyModel>>#descriptionA
<magritteDescription>
^self class descriptionA
MyModel class>>#descriptionA
<magritteDescription>
^MAStringDescription new...
Any clues?
Esteban A. Maringolo
I've prototyped a simple inspector for the Pillar document model on Pharo:
http://youtu.be/6PrTaROp05c
What do you think?
--
Damien Cassou
http://damiencassou.seasidehosting.st
"Success is the ability to go from one failure to another without
losing enthusiasm."
Winston Churchill
Many thanks to Stephan Eggermont, Tobias Page, Esteban Maringolo and
John McKeon for their responses on the SmallWiki and Seaside lists.
It's clear to me now that my problem was trying to load Seaside,
Magritte and Pier Configurations without fully appreciating the details
of Metacello and of Configuration loading options.
The method, #asComponent, wasn't missing; apparently I had loaded a
configuration that didn't include it.
For now, I will use the forum image suggested by Stephan for my current
study of Magritte, and then review further the details of Configurations
and loading options.
Thanks again to all of you for your patience and guidance.
Bruce
Hi all,
I’m playing with pier and want to be able to redirect automatically from a “forbidden” response to the “login” command targeting the forbidden structure.
Can anyone direct me to the class/method I should be looking at to see how this works?
Thanks in advance.
Cheers,
Phil
Further to my previous post on this subject, I looked into a
Seaside-2.8.4 image
to find that:
1. The method, asComponent, is in the class Object.
Object >> asComponent
^self description asComponentOn: self
2. The method, asComponentOn:, is in the class MAContainer.
MAContainer >> asComponentOn:
^self componentClass
memento: (anObject mementoClass
model: anObject
description: self)
I haven't found these methods in Pharo3/Seaside3/Magritte3.
How are components created from descriptions without them?