On Fri, 19 Jan 2007, Grant Baillie wrote:

We can almost certainly replace a lot of the initialValue uses with defaultValue, especially for values that aren't references. There's some risk there, because the return value Item.hasLocalAttributeValue() is different in the two cases, and some code (ICalendar/sharing, maybe) could rely on that.

So far as reflists go, there are really two approaches in use right now:

1) Use defaultValue=None in your attribute.

(Example: EventStamp.modifications or EventStamp.occurrences)

Then, always make sure you can deal with None when iterating over myAttr. If you have a biref, let the repository take care of setting up the biref where possible, by always assigning to the "other" end. This avoids a lot of checking for None, and initializing the attribute to [] (or set() or {} as appropriate).

I could add support for new None-style reflist value, such as Nil, which can be iterated, thereby saving everyone from having to first check whether they have None or a valid ref list.

Currently, I already have such a value, Nil, but it is expressly meant to be NOT persistable. I could add another one, called Empty, of the same type that can.
Nil works as follows:
  - Nil is not true
  - len(Nil) == 0
  - Nil() -> None
  - 'blah' in Nil -> False
  - iter(Nil) -> iterator that stops right away
  - Nil is immutable

2) Use initialValue=[]

(Example: Reminder.reminderItems)

As you noticed, this leads to an extra attribute assignment every time you create the Item. It does, however, make for simpler code: you assume that attribute always exists, and just iterate over it, call add()/remove()/whatever on it, and all's well. Unfortunately, it also has the downside that initialValues don't always get set (if items are imported via sharing, __init__ and initialValues are bypassed), which leads to bugs.

Yes, that's one problem. The other problem is that an initialValue, when set, is a local value and having lots of empty local values eventually adds up too.

(As an aside, there's a movement afoot -- mainly PJE's work -- to have initialValues in Stamp subclasses only be set up when the stamps are actually added. This would probably cut down on some of the empty collection values in your report. cf.

That would be great and probably address a large part of what my original mail was about.

Anyway, is there a way to have the best of 1) and 2)? i.e. have something that behaved like defaultValue=[], until you tried to modify the collection? i.e. in code:

class MyItem(schema.Item):
...     myAttr = schema.Sequence(schema.Item, magicValue=[])
...
x = MyItem(...)
list(x.myAttr)
[]
x.hasLocalAttributeValue('myAttr')
False
x.myAttr.add(x)
x.hasLocalAttributeValue('myAttr')
True
x.myAttr.first()
<MyItem ....>

I sure could add something like that beyond what I described above. Have a sort of Nil value that knows what to do when one attempts to append to it.

In fact, shouldn't all many-valued attributes behave this way?

That could be useful in many cases, yes.

Is what we're discussing here something I should implement now or are we just discussing various ideas, nice-to-haves ?

Personally, I have no objections to implementing these now.
Let me know...

Andi..
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Open Source Applications Foundation "chandler-dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/chandler-dev

Reply via email to