Re: [Zope3-Users] Re: zope.intid and UUIDs

2007-04-20 Thread Benji York

I really like Gary's suggestions here, which I'll paraphrase:

First create interfaces that content can be adapted to to get a UUID, so 
other people can provide different implementations and those can 
interoperate.  Then, create default implementations that work however 
you like.


Then if you, or one of your users want to use a different, or second 
implementation, the migration will be much easier.

--
Benji York
Senior Software Engineer
Zope Corporation
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Re: zope.intid and UUIDs

2007-04-20 Thread Stephan Richter
On Friday 20 April 2007 10:01, Benji York wrote:
 First create interfaces that content can be adapted to to get a UUID, so
 other people can provide different implementations and those can
 interoperate.  Then, create default implementations that work however
 you like.

This is actually a pattern that we use all over the place. One example is 
lovely.tag. You have a utility providing some functionality, such as a UUID 
generator and then use an object adapter to access it more conveniently.

What *I* like about about the proposed solutions is to reuse the intid 
utility.

Regards,
Stephan
-- 
Stephan Richter
CBU Physics  Chemistry (B.S.) / Tufts Physics (Ph.D. student)
Web2k - Web Software Design, Development and Training
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Re: zope.intid and UUIDs

2007-04-19 Thread Gary Poster


On Apr 19, 2007, at 12:56 PM, Derek Richardson wrote:
We've talked a lot about the composition alternative to my idea,  
but we haven't talked about my idea much. What is suboptimal with  
the way I'm proposing, other than that it requires changing zope core?


Martin Aspeli had some concrete things to say about why subclassing,  
your proposal, is suboptimal in comparison to composition.  He cast  
it as why composition would be better, which is simply the mirror  
image.


His first point is particularly interesting: the composition approach  
might let Plone users leverage your code, which introduces it to a  
large community of users.  They (or Zope 2 core?  not sure) have  
their own intid utility.


Composition will be simpler, both in the short and long term; or, if  
you prefer, to relate it to your proposal, the subclassing approach  
is suboptimal in comparison.


Some more thoughts, FWIW:

- I suggest that the implementation should be hidden away.  One  
should be able to adapt an object to something like IUUID or  
IUUIDProvider.  That way we can implement a variety of solutions,  
including a direct key-reference-to-UUID mapping, a intid-to-UUID  
mapping, a simple annotation, or other approaches.  In other words,  
IMO, the main feature of your package should be an interface (or two,  
see below).


- I imagine you also want to be able to find objects for a given  
UUID.  I'd suggest an interface for that, which is used to look up a  
utility.  Again, the implementation may vary.


- In terms of your default implementation, the integer-based approach  
is interesting as a building block because there may be different  
integer sources for a given object, not just intids.  For instance, I  
have an app in which I have integer identifiers for virtual objects,  
which may be fulfilled with different real objects based on current  
state.  One app might want UUIDs to be generated for the virtual  
object, while another might want UUIDs for the real objects (so  
intids based on the standard persistent object key references would  
be appropriate).



Or is that a good enough reason to not do it?


No, but that certainly raises the bar, as you'd expect.

Gary
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-19 Thread Philipp von Weitershausen

Derek Richardson wrote:

Philipp von Weitershausen wrote:

Derek Richardson wrote:
I sense that I'm missing the point here. Perhaps you can elaborate on 
what you mean when you say use and collaboration. I usually know 
what those terms mean, but I'm not sure I am getting it in this context.



The paragraph definitely seems to miss the point, so let me speak code::


  class UUIDUtility(Contained, Persistent):

  def __init__(self):
  self.uuids = IOBTree.IOBTree()
  self.intids = OIBTree.OIBTree()

  def getObject(self, uuid):
  intid = self.intids[uuid]
  return getUtility(IIntIds).getObject(intid)

  def getUUID(self, object):
  intid = getUtility(IIntIds).getId(object)
  return self.uuids[intid]


I'm omitting several seatbelts and various functions to add/remove 
objects from the UUID utility, but I hope you'll get the idea.


With the composition approach, the actual utility class may be a little 
shorter than simply copying the whole thing, but I'll still have to copy 
and just change the names on a bunch of stuff in interfaces.py (IIntIds 
- IUUIDs, IIntIdsQuery - UUIDSQuery, etc).


Perhaps. You could also come up with a shorter/easier/... API, though I 
see how it is compelling to model after the IIntIds API.



And I'll have to copy most of the tests.


You better have good test coverage for your utility anyway. That 
argument doesn't count :).


Martin and Gary pointed out other good reasons why not to go with 
subclassing: the standard intid utility doesn't work in all 
environments. Apparently in Zope 2 you'll need a slightly differnet 
implementation. If you just defer to it via utility lookup, your UUID 
utility might actually work on both platforms, as long as there's an 
intid utility. It makes things more flexible.


The subclasses are pretty much complete as written here and the 
BaseIdUtility is just a minor abridgment of IntIds. This allows all the 
interfaces (other than the two empty markers and the events) to be 
reused between intids and UUIDs and most of the tests can be performed 
for both, as well.


We've talked a lot about the composition alternative to my idea, but we 
haven't talked about my idea much. What is suboptimal with the way I'm 
proposing, other than that it requires changing zope core? Or is that a 
good enough reason to not do it?


Your subclassing idea has a lot of appeal to it. To answer your question 
what's suboptimal about it: you'll have to wait till the next Zope 3 
release cycle to actually make use those modifications. Also, like I 
said above, the composition approach allows you to be more flexible.



--
http://worldcookery.com -- Professional Zope documentation and training

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-19 Thread Derek Richardson

Philipp von Weitershausen wrote:
Martin and Gary pointed out other good reasons why not to go with 
subclassing: the standard intid utility doesn't work in all 
environments. Apparently in Zope 2 you'll need a slightly differnet 
implementation. If you just defer to it via utility lookup, your UUID 
utility might actually work on both platforms, as long as there's an 
intid utility. It makes things more flexible.


Hmmm. I've looked in Zope 2.10.3 final (the earliest release I may 
target) and zope.app.intid is the same between Zope 2.10.3 and Zope 
3.3.1, except for the presence in 2.10.3 of 
zope.app.intid-configure.zcml, which is just a slug. Am I looking in the 
wrong place?


Your subclassing idea has a lot of appeal to it. To answer your question 
what's suboptimal about it: you'll have to wait till the next Zope 3 
release cycle to actually make use those modifications. Also, like I 
said above, the composition approach allows you to be more flexible.


OK, yes, this is a problem. I'm targeting on Plone 3.5 (for the final 
product, not the uuid utility alone), but I'd like to be 
backwards-compatible with Zope 2.10.x. So, yes, I'll have to provide a 
complete backwards-compatible package.


I've thought about it and decided that these two proposals (subclassing 
and composition) are partially orthogonal. Half of subclassing is simply 
genericizing the interfaces; composition is a matter of implementation. 
For proof, consider that we could have a UUIDs that implements IIDs and 
defers to an IntIds for implementation, which also implements IIDs. This 
might reduce the benefits of code reuse, but would still gain the 
benefit of one set of interfaces (aside from the IntIds and UUIDs markers).


So, my plan. I am going to copy IntIds, genericize the interfaces, and 
split the superclass from the subclass as mentioned. I'm going to do 
this in my package. I will provide a UUID implementation but not an 
IntId implementation. That way if, in the future, y'all decide to move 
towards this in the core, there will be a pre-existing implementation 
and I'll be ready. You could include just the interfaces, the interfaces 
and the utility superclass with a new IntIds subclass without the UUID 
implementation, or you could include everything - it's up to you. And, 
if you don't, then I haven't lost anything but 15 minutes of time.


As for implementation, I'm going to have to think through whether 
composition is appropriate for my use. Another advantage of genericizing 
the interfaces is that this is an implementation detail - I may provide 
two uuid implementations, one that is composed by intid and one that is 
not. I may also rethink the implementation of the base utility class to 
see if I can maximize reuse between these two cases. And, having this 
flexibility will help me later if I run into trouble backporting to Zope 
2.10.x. A fun project!


The code will be in the Vice project in the Plone collective, for now, 
in the packages collective.id and collective.uuid.


Thanks,

Derek

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-19 Thread Martin Aspeli

Derek Richardson wrote:

Philipp von Weitershausen wrote:
Martin and Gary pointed out other good reasons why not to go with 
subclassing: the standard intid utility doesn't work in all 
environments. Apparently in Zope 2 you'll need a slightly differnet 
implementation. If you just defer to it via utility lookup, your UUID 
utility might actually work on both platforms, as long as there's an 
intid utility. It makes things more flexible.


Hmmm. I've looked in Zope 2.10.3 final (the earliest release I may 
target) and zope.app.intid is the same between Zope 2.10.3 and Zope 
3.3.1, except for the presence in 2.10.3 of 
zope.app.intid-configure.zcml, which is just a slug. Am I looking in the 
wrong place?


Yes, it's there, but that doesn't mean it *works* in Zope 2. You should 
look at five.intid, which is an attempt to make it work in Zope 2.


Martin

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-18 Thread Philipp von Weitershausen

Derek Richardson wrote:

All,

I've decided to go ahead and write an RFC 4122 UUID utility based on 
zope.intid (this is for a Plone SoC project, but this bit is pure Zope 
3). I wrote most of it today and there is more code shared between the 
two than is different. The main differences are:


* OOBTrees, instead of an IOBTree and an OIBTree
* Different events are fired when an object is registered and 
unregistered (they could be merged, but this is easy 
backwards-compatibility)

* _generateId() is, of course, different

The rest is pretty much copied and pasted, even most of the tests.

My question is: should the common parts be abstracted out into a 
framework for id utilities, of which intid and uuid will be two 
instantiations? I know this is a small amount of code but:


* I hate copy and paste
* I hate the idea of bugs in two places (implicit coupling, from a bug 
fixer's perspective)
* Larger codebases mean more to read to understand what is going on for 
newbies, like me


Of course, the duplication rule is If you do it three times, you're 
doing it wrong and I've only done it the second time. So, part of this 
question is whether anyone can see a future need for any id utilities 
other than intid and uuid. If so, I think this would definitely be a 
good move. Otherwise, I'm up in the air.


Of course, this would be a change to zope core, which is the main reason 
I'm leery. I will be sending in my contributor agreement tomorrow. So, 
I'm really wondering whether this is worth changing in the core or 
whether we shouldn't bother.


In the spirit of Benji's suggestion, why don't you try to make the UUID 
utility *use* the intid utility? Basically, the UUID utility would 
simply keep a mapping of intid - UUID and defer to the intid utility 
for retrieving the object from the intid and viceversa.


Speed might be an issue here, though BTrees are pretty fast and memory 
efficient, especially with integers...




--
http://worldcookery.com -- Professional Zope documentation and training

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-18 Thread Derek Richardson

Benji York wrote:

Derek Richardson wrote:
I wrote most of it today and there is more code shared between the two 
than is different. The main differences are:



* OOBTrees, instead of an IOBTree and an OIBTree
* Different events are fired when an object is registered and 
unregistered (they could be merged, but this is easy 
backwards-compatibility)

* _generateId() is, of course, different

The rest is pretty much copied and pasted, even most of the tests.


This suggests to me that you instead want to /use/ an int ID utility, 
not /be/ (a mutated) one.  Unless there's a very compelling reason to 
copy all that functionality composition would be much cleaner.


I definitely don't want to be an *int* id utility. I may want to be, 
however, a uuid variety of an *id* utility, of which another variety 
would be int, and perhaps others, as well.


I see no compelling reason to copy all that functionality, which is why 
I'm exploring alternatives.


*Using* an int id utility, though, doesn't seem to cleanly solve the 
problem, which makes me wonder if I'm understanding you. If you mean use 
the intid utility to map keyrefs to int ids and then map int ids to 
uuids, this has a few problems. What I want to vary is the 
implementation - I want to keep the same interface. This would be 
keeping, and adding another layer to, the implementation and I'll still 
have to re-implement the interface on top of it. That's more work than 
just copying and doesn't reduce the copying at all, as I see it. Plus, 
it'll be (perhaps marginally) slower.


If you mean use the intid utility by instantiating one and then changing 
the data structures and _generateId() and the events at runtime, this 
would indeed solve the need to copy and paste. However, this seems like 
an obfuscating solution - who would guess that what is masquerading as 
an intid utility is really a uuid utility? Perhaps that's my 
static-typing background speaking, but it seems cleaner to have an 
abstract id utility and then write 10 lines of code to subclass and 
turn it into an int id utility and then another 10 lines for uuids.


I sense that I'm missing the point here. Perhaps you can elaborate on 
what you mean when you say use and collaboration. I usually know 
what those terms mean, but I'm not sure I am getting it in this context.


Derek

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-18 Thread Philipp von Weitershausen

Derek Richardson wrote:
*Using* an int id utility, though, doesn't seem to cleanly solve the 
problem,


Why?

which makes me wonder if I'm understanding you. If you mean use 
the intid utility to map keyrefs to int ids and then map int ids to 
uuids, this has a few problems.


Which ones?

What I want to vary is the 
implementation - I want to keep the same interface.


Your UUID utility should be able to keep the same interface. But instead 
of doing a keyref - UUID mapping, it refers to the intid utility for 
keyref - intid and itself only does intid - UUID. This would be 
completely transparent to the outsider.


This would be 
keeping, and adding another layer to, the implementation and I'll still 
have to re-implement the interface on top of it. That's more work than 
just copying and doesn't reduce the copying at all, as I see it. Plus, 
it'll be (perhaps marginally) slower.


Perhaps. That's something to profile.

If you mean use the intid utility by instantiating one and then changing 
the data structures and _generateId() and the events at runtime, this 
would indeed solve the need to copy and paste. However, this seems like 
an obfuscating solution - who would guess that what is masquerading as 
an intid utility is really a uuid utility? Perhaps that's my 
static-typing background speaking, but it seems cleaner to have an 
abstract id utility and then write 10 lines of code to subclass and 
turn it into an int id utility and then another 10 lines for uuids.


I sense that I'm missing the point here. Perhaps you can elaborate on 
what you mean when you say use and collaboration. I usually know 
what those terms mean, but I'm not sure I am getting it in this context.



The paragraph definitely seems to miss the point, so let me speak code::


  class UUIDUtility(Contained, Persistent):

  def __init__(self):
  self.uuids = IOBTree.IOBTree()
  self.intids = OIBTree.OIBTree()

  def getObject(self, uuid):
  intid = self.intids[uuid]
  return getUtility(IIntIds).getObject(intid)

  def getUUID(self, object):
  intid = getUtility(IIntIds).getId(object)
  return self.uuids[intid]


I'm omitting several seatbelts and various functions to add/remove 
objects from the UUID utility, but I hope you'll get the idea.



--
http://worldcookery.com -- Professional Zope documentation and training

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


[Zope3-Users] Re: zope.intid and UUIDs

2007-04-17 Thread Derek Richardson
I have no principled objection to a ZPL license. And I would like the 
code to make it into the core, if appropriate. So, the answer is, a ZPL 
license is likely.


David Pratt wrote:
I like this idea of abstracting the code for ids myself. It will be 
interesting to hear what others have to say. Can you advise whether the 
UUID utility will be ZPL licensed since this is important if you are 
talking about something with generic functionality for z3. Many thanks.


Regards,
David

Derek Richardson wrote:

All,

I've decided to go ahead and write an RFC 4122 UUID utility based on 
zope.intid (this is for a Plone SoC project, but this bit is pure Zope 
3). I wrote most of it today and there is more code shared between the 
two than is different. The main differences are:


* OOBTrees, instead of an IOBTree and an OIBTree
* Different events are fired when an object is registered and 
unregistered (they could be merged, but this is easy 
backwards-compatibility)

* _generateId() is, of course, different

The rest is pretty much copied and pasted, even most of the tests.

My question is: should the common parts be abstracted out into a 
framework for id utilities, of which intid and uuid will be two 
instantiations? I know this is a small amount of code but:


* I hate copy and paste
* I hate the idea of bugs in two places (implicit coupling, from a bug 
fixer's perspective)
* Larger codebases mean more to read to understand what is going on 
for newbies, like me


Of course, the duplication rule is If you do it three times, you're 
doing it wrong and I've only done it the second time. So, part of 
this question is whether anyone can see a future need for any id 
utilities other than intid and uuid. If so, I think this would 
definitely be a good move. Otherwise, I'm up in the air.


Of course, this would be a change to zope core, which is the main 
reason I'm leery. I will be sending in my contributor agreement 
tomorrow. So, I'm really wondering whether this is worth changing in 
the core or whether we shouldn't bother.


Thanks,

Derek

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users



___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users