If you haven’t yet read Ovid’s post about the ‘AuthenticationFairy’, you should. Go on, you can rejoin me below the fold for discussion of some scary Perl…
Apart from offering a very powerful way of thinking about Objects and OO analysis, Ovid touches on something that niggles me about Rails1; the way ActiveRecord works.
Yes, yes, ActiveRecord’s brilliant, as an implementation of the Active Record pattern, it’s pretty exemplary.
I just don’t like the pattern. Back when I was a dedicated Perl programmer, I worked on an object persistence system which Leon Brocard named “The Magic Data Pixie” – we generally just called it Pixie – which was a very different kind of persistence tool.
Pixie’s goal was to make objects persistent. All of them. Regardless of their source. You just wrote your application, connected your objects together appropriately, then threw a ‘top level’ object to the data pixie and asked it to store the object for you and associate it with a given key.
Later, you could ask pixie to fetch the top level object you’d stored, and just carry on using it as if it’d always been resident in memory. Pixie handled proxy object, deferred fetches from the database, all the backstage stuff needed to maintain the illusion that everything was resident in memory and always had been.
It wasn’t perfect, but we kept the illusion going; objects didn’t know, or care if they had been persisted, the data store was garbage collected (mark and sweep, triggered by asking Pixie to run a sweep for you), objects were unique – you’d never have two objects in memory with the same id.
Quite deliberately, we didn’t have a query language; the idea was that you got into the data store through known entry points and, if you needed to do searching or indexing or whatever, you could write your own. The plan was to discover what sort of searching would be needed, and implement that.
As ‘one to throw away’ I’m really rather proud of Pixie. It fell down on locking – we tried to add it later, and that really, really didn’t want to work. If I were starting with a clean sheet, I’d worry about that far earlier and probably try and use optimistic locking to implement something transaction – there’s at least one Smalltalk persistence engine that has some good ideas here, I just can’t remember what it’s called.
I’d also look at a hybrid scheme. Pixie was essentially one big table with an id column and a blob – not exactly scalable. With a sensible scheme for describing classes, it should be possible to have one big table for some objects and ActiveRecord type tables for things that you want to search. Jifty’s persistent objects do some very clever things in this regard.
Metadata would be useful in another respect too. ActiveRecord’s validations, errors and helpers like
input 'variable', 'field' all use a pretty restricted set of ActiveRecord metadata. A class description language (or an appropriate set of class methods) that could implement compliant
attributes and the others could be very useful…
I suppose the question is, could I implement it? Pixie poked in some very odd corners of Perl to get the behaviour we needed. One example was the mementos that could replace themselves with the ‘real object’ they’d fetched from the database. They were all instances of
Pixie::Cookie with an
AUTOLOAD – perl’s equivalent of
method_missing that went to the database for the data, populated its ‘instance variables’ and then changed its own class to ‘become’ an instance of the appropriate class.
Hmm… I feel the need for a spike…
1 There’s lots of stuff that niggles me about rails. Nothing that makes me want to throw it out and start using something else – yet, but I’m still waiting for Perl 6.