At 09:46 PM 5/19/00 +0400, Jephte CLAIN wrote:
Some thought about RackMountables: they should subclass Acquisition.Implicit for bobotraversing to work. indeed, the __bobo_traverse__ code says:
return getattr(ob, 'aq_base', ob).__of__(self)
ob has the __of__ attribute only if it subclass an extension class (Acquisition.Implicit is an easy choice)
Good point, but ordinarily one mixes RackMountable with another Zope class such as SimpleItem.Item, or uses it as part of a ZClass. In either case, Acquisition gets added in. I prefer to keep the base class as free as possible of things that will be mixed in later to avoid repeated inheritance. Also, for what it's worth, future versions of RackMountable will define their own __of__ method, as it will be required to support placement of rackmountable-ish objects in places other than racks.
in AttributeProviders.py, around line 199, definition of _DelAttributeFor is bogus. Instead of:
Noted and fixed for next release.
It is desirable for me to enumerate the objects stored in the racks for a specialist. Because the __readableStorage is not accessible from derived classes (magic of ExtensionClasses ???), I can't add that behavior without patching Rack.py
I'm thinking of a method 'rsValues' that enumerate values in the readableStorage. In Rack.Rack:
def rsValues(self): """rsValues like 'readableStorageValues' why on earth are there __readableStorage and __writableStorage ??? """
__readableStorage and __writeableStorage are designed to prevent side-effect transactions occurring. It's a little bit tricky, but basically __readableStorage doesn't create a storage if it hasn't already been created - it instead returns an empty dictionary. __writeableStorage creates the storage if it doesn't exist. Thus, operations that only intend to read data from the storage don't cause a write transaction when the storage doesn't yet exist.
values = [] slots = self.__readableStorage.values() for slot in slots: # the following took from retrieveItem item = slot[SelfKey] item._setSlot(slot) item._clearPerTransactionCache() # associate the rack to the item item._setRack(getattr(self, 'aq_inner', self)) ## the above line could be written # item._setRack(self.aq_inner) ## if racks objects where always wrapped. values.append(item) return values
Or is it best to create a catalog in the specialist that index all objects stored in the rack as they get added?
Yes, that is the best route for the current version. Future versions will support an "Indexes" tab for plugins that manage search and retrieval. This tab will be on both Specialists and Racks, as well as on the new ZDataManager class that allows Providers and Indexes on objects stored in Folders or other "normal" ZODB locations.
The default ZODB storage should give the ability to enumerate the objects, even if it does not belong to the standard "interface" of the rack.
Something like that will be included, but it will be in the form of a plugin that goes on the Indexes tab, which the Rack can call. At that point, searching/enumerating *will* be part of the Rack interface.
I understand now that the RackMountable is only a placeholder class, and that attributes and sheets are managed by AttributeProviders and SheetProviders, right?
That is correct. RackMountables are like abstract classes that only have domain knowledge (application-level intentions) with no data storage implementation knowledge. In ZPatterns 0.4.0 and beyond, RackMountables will probably change their name to DynamicDataObjects, or DDO's for short. This is to reflect their new, wider scope, which does not require them to be mounted in a Rack to have their dynamic features. They will be able to have providers manage their data no matter where they are in a Zope application, so long as the DDO is in acquisition context of a ZDMFolder ("Folder w/Data Management Support") that has a ZDataManager plug-in registered for the DDO's meta_type. I'm not actually real fond of the DDO term, because "Dynamic Data Object" doesn't quite do justice to what these things actually are. I am definitely open to suggestions for a better name. (Facade? PlaceHolder? InsideOutObject? ExternalDataObject? BrainInjectedObject?) Also, while I'm babbling about versions, it's important to note at this point that ZPatterns versions below 1.0.0 should be considered subject to change even with respect to developer-level API's. They get more stable as the number gets higher, which is why LoginManager changed a lot less between 0.8.0 and 0.8.5 than half as much as ZPatterns changed between 0.2.0 and 0.3.0. The change to 0.4.0 will probably be another big jump, due to the DDO stuff as well as the Indexes stuff. Predicates may even make it in, in some small way.