Ken Irving - 2008-02-13

There may be a need to check that an object matches a particular version of its class, but I don't have a mechanism for this, nor am I sure that such a mechanism is appropriate.

An object foo of class Foo might be created at time t1, when Foo implicitly assumes certain data structures in foo.  Later, at time t2, Foo changes some part of the assumed data structure (for some good reason, of course), and so now the object foo is not compatible with its class.

I tried to address this (in just such a case) by putting the class version in list property @version; a Foo method could check that the object version matched its internally defined version, and fail if different.  This worked well until I used the same mechanism in a subclass, still with only one version property value in the object.

I guess the obvious solution is either 1) to not care about versions (which could cause some breakage), or 2) to store the object's class version in hash on the class name.  1 is perhaps not much of a choice, as I can imagine (and have seen) cases where a class is changed, resulting in incompatibility with corresponding objects. 2 seems workable enough, but represents a higher level of constraints than the rest of the thinobject scheme, perhaps too uncomfortable to require.

The class defines the behaviors of an object, and really needs to be in sync with the object.  When invoked, the method starts operating on the object, and if some data structure isn't there or is different, it won't work.

I guess another option, 3) would be to ``not do that''.  Once defined, a class can not be changed.  But that's just not realistic.  In developing applications, I cannot count on getting it right the first time, and so change is going to happen.  I can't afford to clutter the namespace by then having to rename the new class -- although I could perhaps leave the old class in place with the version appended to the name, so that the nominal class name can stay the same.

If the class version is defined by data structures, then maybe it's possible to explicitly check for those structures in the object; i.e., do a compliance test within the method.  That sounds very expensive, though, when what I really want to do is to just execute the method.

I think that, for now, I may forgo the version check, and instead just (e.g., manually) make sure that the objects are kept up to date.  That doesn't scale, but could be sufficient for my purposes at this stage, with a very limited scope of deployment.

A version hash could be simple enough, or the values could be stored in the default hash, ``%''.  Entries might look like:

    version-TimeSeries = 0.3
    version-Schedule = 0.1

(I arbitrarily put version as prefix so that the entries will sort together.)  I guess that's the right, and only reasonable choice of hash.  Any specific alternate choice, e.g., %version or %VERSION, would clutter the namespace, possibly colliding with a specific need down the road.  Another form of the same thing:

    VERSION:TimeSeries = 0.3
    VERSION:Schedule = 0.1

Ideally, this could be left up to the class itself, and wouldn't need to be a system-defined protocol.  After all, the check is made by the methods themselves, and they're the only things that care.  So the particular form of hash entry is arbitrary, and not a concern of the thinobject system.

Note that the latter form of the entry could be stored in the class as a file property, e.g., an empty file named ``VERSION:TimeSeries=0.3'' would exist  in the class namespace.

A real concern, though, is that we're now using the class name over and over, so it's more tightly coupled to the classes and objects.  Inasmuch as the class name is defined by the directory name containing it, maybe it's enough to leave the name as implied, so the property file would be ``VERSION=0.3''.  That would be better, I'm pretty sure.

Any class that cares about this version business could add the entry in a new method.  I've to date only used classes where one new method was called (in addition to the built-in, bootstrapping, thinobject new method), but it should work that each new method in a class hierarchy should be called in turn.

Of course, that now means that Foo.new needs to know its own class name. Is this reasonable?  This is another form of coupling; the class name doesn't actually exist (now) other than as the directory name.  Maybe Foo.new could do something like

    #!/bin/sh
    self=$1
    echo Foo=0.2 >> $self/%

but of course this ignores the problem just posed.

I don't think pwd can be used; at most, we can cd to the object (e.g., cd $self), but may well not be able to cd to the class.  Also, we have no way to know whether we're the immediate parent class or somewhere further along the chain of class links, so cannot do:

    cat $self/^/\@VERSION >> $self/%

We could, however, resolve the class link to a name, and then check for the version class property.  Note that Foo.new runs in the context of the object, not of the class.

I think that using the default hash is appropriate, but I don't know if this is something we want to automate in the built in, root new method.  E.g., we could check each for @VERSION in each class, and add VERSION:Class=$v to the object's hash. By so doing, though, we suddenly have added a systematic constraint to the whole system.  No, I don't want to do that.

So the answer must be to do all necessary work in the class new method, if it cares enough to do it.

I think I'll drop this for now, leaving it unresolved but at least leaning toward a solution or at least some viable approaches to consider.