Very interesting reading, Naftoli! Thanks alot for such extensive explainations. I'm going to read your message again and again until i understand it all :)
On 13 окт, 02:09, Naftoli Gugenheim <naftoli...@gmail.com> wrote: > 1. Personally I would not take the approach of creating a totally new ORM > with a completely new paradigm just to eliminate the object syntax. > > The first step, as with anything in life, is to define our goals. What > exactly is it about the object syntax that's problematic? Is overridability > a problem? Is reflection evil? Let's make a list of our objectives over > here. > In any case, I would take the following approach. > Currently, the way Mapper works is as follows. Every Mapper instance > delegates database actions to its MetaMapper instance, which, upon > initialization, builds the information about its fields using reflection, > including the list of fields and their names. > Three reasons for the object approach were mentioned in this thread. > > 1. To allow access to members. It was mentioned that this is now possible > with anonymous classes (val x = new Y { ... } ). What was not mentioned but > I read elsewhere IIRC is that the latter is implemented by scalac via > reflection. Not that that's the end of the world, especially as we're > relying on reflection as it is. Also, at least the argument remains--allow > one to choose whichever syntax one desires. On the other hand, if Mapper > would not use reflection, objects, being lazy, would not be known about > until initialized, thus requiring the user to manually reference them. > 2. To disambiguate members that reference or return other fields. > However, this argument assumes that the list of fields is built via > reflection; maybe it should not be. > 3. To allow the field names to become available via reflection. I don't > there's any way around this other than a compiler plugin (or maybe > scala.reflect.Code?) So my suggestion would require passing the field name > to a constructor. On the other hand, as I mentioned in a previous post and > will explain better below, passing "this" to the constructor can be > eliminated. > > So the first reason basically says, "since people may need to use 'object,' > and objects are lazy and we won't necessarily know about them, we had better > use reflection." On the other hand, if we use vals most of the time, the > constructor itself can inform the MetaMapper of its existence, and if > someone wants to use 'object' or 'lazy val' then they will be required to > initialize it before using it with Mapper. > The second reason is eliminated if we don't use reflection. > The third reason remains valid but the question is how important it is, at > the expense of preventing subclasses from overriding fields. > > If it is acceptable to eliminate the "this" parameter and instead require a > field name parameter, then it would seem possible to use a val based system > instead of an object + reflection system. > > Here is how it would work. > class Field(name: String)(implicit meta: MetaModel) { > meta.register(this)} > > class Model { > implicit def meta = getSingleton} > > ==== > class MyModel extends Model { > val field1 = new Field("firstname") // meta gets passed automatically > val fieldRef = field1 // doesn't cause duplication because fields are > registered on instantiation} > > val fieldX = new Field("lastname") // compiler error because no implicit > MetaModel in scope > val fieldY = new Field("xxx")(MyModelMeta) // works, but obviously a bad > idea > > Two points. > > 1. The concept of the meta being passed implicitly could probably be > implemented into the current system. The only thing it has to do with this > discussion is that if you would have to pass 'this' and the field name it > would be really verbose, so I'm just pointing out that we could have a > non-reflection-based system with about the same verbosity that we use now, > although we could make the current system less verbose too. > 2. On the surface it would seem impossible to implement this in Mapper, > because by not using reflection there's no way to get all the object > members > since objects are lazy. However since the reflection system only picks up > objects and not vals, one could solve this as follows. As long as the same > field cannot be registered twice, i.e., registration of a field skips it if > it's already registered, there's no problem with allowing both methods to > exist side by side. Let MappedField or some class or trait high in the > hierarchy call a register method on the MetaMapper upon its initialization. > This will register all val fields, as well as any object fields initialized > early. Then, when the MetaMapper goes through its reflection process, any > previously register fields will be skipped. > > However a basic problem with my approach may be the following. Say we have > instances a and b of model C, if a field is a val, not a new class, what > prevents that field from being registered twice? In other words, how can > fields in multiple instances of a given model be recognized as being the > same field? One answer, though maybe not the best, is through the field's > field name. > > 2009/10/12 Naftoli Gugenheim <naftoli...@gmail.com> > > > > > So Model represents the database connection? > > > 2009/10/12 Oleg G. <ojo...@gmail.com> > > >> On 13 окт, 00:08, naf g <naftoli...@gmail.com> wrote: > >> > Why do you have two classes, Model and Record? What are they and why are > >> they interdependent? > >> I thought about Model being a place for metainformation (like database > >> structure, options/properties etc), or maybe it can be described as > >> global context for Record-related activity. They are dependant to > >> allow Field operations to reach the context. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~----------~----~----~----~------~----~------~--~---