On Sun, Mar 14, 2010 at 02:30:48PM -0500, Peter Karman wrote:
> I like this approach. It's more work for KS developers, in terms of managing
> api versions, but that's good work to do, since it requires making the api
> changes very explicit.
I understand that this sounds attractive in theory, but it's not practical.
Certainly having two versions run side by side won't ever work. We can't
search-and-replace within compiled XS objects to substitute "KinoSearch" for
"KinoSearch3". Does Query_Is_A(query, ORQUERY) pass, fail, or segfault
when "query" was created under KinoSearch3, but ORQUERY is a VTable owned by
KinoSearch4, aliased to KinoSearch? What should factory methods spit out, and
how will they know? How will type checking across the Perl/C border work?
Changing up behaviors using an api_version key can work within a single
object, using one of the following strategies:
* Store api_version as a member variable and switch up behavior based on
its value. That's what HTML::Parser does, I believe.
* Have the constructor dispatch based on api_version and return objects
blessed into different classes.
* Store an API-specific object within the main object and dispatch to that.
However, KinoSearch is a highly performance-sensitive library with hundreds of
classes and lots of interaction between all the various parts. Furthermore,
it doesn't use hash-based method dispatch, but compile time binding -- which
is much faster, but also means that invoking an invalid method on an object
results in a memory error rather than a catchable exception. At best that's a
segfault, at worst it's a security hole.
Marvin Humphrey