Roché Compaan wrote:
On Thu, 1 May 2003 23:30:04 +0200 Roché Compaan <roche@upfrontsystems.co.za> wrote:
Something like ComputedAttribute or descriptors should make it possible. Hmm, I might just have thought of a way to do this with ComputedAttribute which I'll try tomorrow. But ComputedAttribute is Zope2 specific isn't it? Darn ...
It looks like ComputedAttribute has no dependencies on Zope 2 code so I had a go at another API addressing specifically the way in which objects use relationships.
The work you did looks good, but at this point I'd still like to call the work you did a proof of concept. The next step is to write a proposal that others can comment on. A long discussion like this is hard for others to follow, but a proposal sums up everything we learned.
I used the Relations class in mxmRelations as is since it has no Zope dependencies. How this will be made accessible as a different branch in the ZODB (iow where it will be stored and how you will locate it) and how the Relations API must be extended still needs to be addressed.
One request: the word "relation" should not appear anywhere in the API. We should use "relationship" consistently. I'm pretty sure that relations are only one possible implementation of relationship storage.
I assume all objects have ids. This is not a requirement and if we drop this assumption very little in the implementation have to change.
We can't make the assumption that all objects have IDs. One of the requirements is that either direct or indirect references are possible. All of the requirements should be listed on the proposal.
I do not define Relationships as static attributes since we need a handle on the class instance to relate.
That's what computed attributes and descriptors are for.
from Relations import Relations # This is the Relations class in mxmRelations import ExtensionClass from ComputedAttribute import ComputedAttribute
class Relationship(ExtensionClass.Base):
def __init__(self, ob, relation, cardinality): self.ob = ob self.relation = relation self.cardinality = cardinality
_r_ = ComputedAttribute(lambda self: self.relation._get(self.ob))
Actually, I meant for this class to be a ComputedAttribute/descriptor. This class does not need to use computed attributes.
def __getattr__(self, name): l = self._r_ if self.cardinality == 'single': return getattr(l[0], name) else: # This can optimised: Relations can return a BTree that we # can subscript for ob in l: if ob.id == name: return ob
def add(self, other): # TODO: test if 'other' is not a sequence if our cardinality is # single self.relation._relate(self.ob, other)
def remove(self, other): self.relation._unrelate(self.ob, other)
student_courses = Relations() term_courses = Relations() # this relation will be between an object that knows it relationships and # instances of third party objects that doesn't school_courses = Relations()
Note that you did not arrange for the relations to be stored in ZODB at all. I'll help you deal with that once we've prepared an API. If you have some time, I'd appreciate it if you started a proposal on a wiki page. Then we'll come up with an API. Once we're satisfied with the API, we'll ask for comments. Shane