[Nitro] Concerns over Og mandating the form of initialize

James Britt james_b at neurogami.com
Wed Apr 13 19:05:11 EDT 2005


George Moschovitis wrote:
>>applications to be able to create or alter data. I see this as a feature.
> 
> 
> ok...
> 
> 
>>When my Nitro app reads data and creates objects, I want to be sure the
>>created objects are well-constructed.
> 
> 
> you can add a og post-read callback to validate the object. (In the
> next version this will be much easier and powerful, thanks to the
> aspects).

I think the central issue is, How much code has to be changed or added 
in order to get some sort of persistence and automatic object creation.

The other issue is, what is being saved/retrieved: objects or data?

>  
> 
>>What would be the overhead of saving an object's properties as simple
>>data, but also using an extra field to store a YAML serialization, and
>>...
>>values in the database, or revive existing objects from the saved
>>serialization?
> 
> 
> this feels wrong. You are duplicating the data. Plus there is another
> problem. If you attach a yaml representation to every DBMS row, you
> cant have constant length records (which are much faster to traverse
> by the DBMS system).

Yeah, I'm not crazy about the idea.  It solves some problems, but it's a 
hack.

> 
> BTW, I think it is wrong to call the initialize method when an object
> is deserialized. In the initialize method I may put code that should
> be called when the object is initialized, ie created for the first
> time. 

This is an important issue, though.  When a row is retrieved from a 
table, is it to restore a specific object, or to drive the creation of a 
new object?  The later is not deserialization (to my mind), and leaves 
open the idea that the data  may come from a variety of sources.

So, yes, with deserialization one should not be calling the constructor, 
but objecting to calling 'new' presumes that deserialization, rather 
than object creation, is the goal.


> For example I could have code for reference counting in the
> constructor:
> 
> def initialize 
>   Statistics.num_of_blogs += 1
> end
> 
> It would be bad to force this code executed every time the object was
> deserialised.
> 
> If you want to ensure a valid state for your object you could do the
> following (some 0.16.0 concepts here):
> 
> class MyObject
> 
>   # 0.16.0 aspect to intercept lifecycle callback
>   post :make_valid, :on => og_read
> 
>   def initialize(...)
>      ...
>      make_valid
>      ...
>   end
> 
>   def make_valid
>     # ensure a valid state for the object
>   end
> 
> end
> 
> then make_valid is called after (post) each object is deserialized (read) from
> the DBMS.
> 
> does this make sense to you?

Sort of, but not in a way I like.  I have this mental model around 
Nitro/Og, where one can write an application in the simplest form, and 
not have to commit to design or code idioms mandated by the framework, 
until such time that the need arises.  And when such changes are 
required, that they are minimal or automatic  by virtue of 
meta-programming.

If I'm designing an application, with no presupposition abut what data 
will be saved, then I'm probably going to build classes with initialize 
methods designed to enforce constraints.

If, later I decide to Oggify some classes, I would prefer to make as few 
changes as possible.  Changing attr_* to prop_* is trivial, and there is 
a clear need for it.    Having to rework the constructor, and add new 
methods that only make sense when used with Og, seems more burdensome.

It may be that, in order to get a fair level of robust O/R, assorted 
concession have to be made.  I just want to be sure they are small.

An alternative to using a block to instantiate am object is to require 
persisted classes to use a hash (i.e. named arguments) as the sole 
argument, and og_read or whatever would then create this hash from the 
table data and pass this into new.

This still does not allow quite enough freedom in class design; I may 
want a class that requires certain arguments, but also exposes 
properties that are only set though methods, not the constructor.  So 
code would still need to call all the attribute setters.

For what its worth, I'm somewhat skeptical of saving and restoring 
objects as objects, rather than creating new objects from saved data, 
because I think you end up trying to have a virtual object database that 
has to sit atop assorted relational databases. On the other hand (of 
course), I'm intrigued by the idea of a framework that completely hides 
the notion of any relation database underpining; you just code as if all 
you have are objects, and saving restoring deals with specific objects, 
not relational data.

James



More information about the Nitro-general mailing list