I finally got around to writing some documentation (reprinted below from
), so I figured this was a good time to announce. Load "Magritte-Merging"
from my GH fork 
Let's say you have a Person object with a Name. Maybe you are in the
marketing domain, and info comes in through various lists (say csv or Excel
files). Some of these may contain missing, incomplete, or incorrect
information. When new info comes in referring to the same person, you'd like
to take the most correct parts of both the existing and incoming data.
Main entry point
The well-known #patchRelativeToBase:, which we borrow from Monticello.
newObject patchRelativeToBase: existingObject returns an MAPatchMacro which
contains a MAPatchOperation for each description of interest. "Interesting"
here means that the description:
1. The field has not been excluded from merging
2. The new value is interesting
3. Excluding a field from merging
Just do anElementDescription shouldMerge: false. Why would you want to do
this? Continuing our Person example, let's say we have a virtual #fullName
field which concatenates #firstName, #lastName, etc into a pretty printed
string. The real data lies not in the generated string, but in the
components and will be merged there. NB: maybe a simpler way would be to
exclude #readonly fields?
Is a New Value "Interesting"
The default rules are:
1. The value has changed - duh!
2. The new value is not nil
3. The new value is not the Magritte default value (This should be
implemented. See Issue #19)
These can be changed by overriding #is:anInterestingReplacementFor:,
currently on the domain object level e.g. Name. For example, aName might
want to merge a new value which is a full first name like "James", when the
previous value was an abbreviation e.g. "J.". Obviously, overriding once per
domain object only works when its fields which are all similar. Probably in
the future when the need arises, this should be moved to the element
Merging in Place
By default, field values are replaced with the new values. If instead you
want to keep the existing field value object and recursively update its
fields, in your field type (Name in our example), override as follows:
patchRelativeToBase: oldValue as: description of: receiver
"Edit me in place instead of full replacement like a value object"
^ self patchRelativeToBase: oldValue
This would allow us to consider each update to aPerson's name individually
and not as an atomic operation. We may want to accept the new first name,
but reject the new middle name.