David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea.
But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. And then, to make them private, which is done...that's turning a headache into a nightmare. Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. Glenn... On Aug 27, 12:11 pm, David Pollak <feeder.of.the.be...@gmail.com> wrote: > On Thu, Aug 27, 2009 at 11:22 AM, glenn <gl...@exmbly.com> wrote: > > > David, > > > Returning menu items from your init function is OK, but forces the > > user > > of your module to guess on function-call order > > I don't understand... what function call order are you talking about? The > order in which the modules are initialized? Something else? > > > , or be forced to glean > > it from > > the source, which he should not be required to do. > > > Putting code such as this, instead, in your init function helps, but > > does not eliminate that problem. > > What particular problem? > > > > > val sitemap = LiftRules.siteMap match { > > case Full(sm) => LiftRules.setSiteMap(SiteMap(sm.menus ::: > > Role.menus:_* )) > > case _ => LiftRules.setSiteMap(SiteMap(Role.menus:_*)) > > } > > Where are you proposing to put this code? > > > > > With it, you can sort of standardize your call-order, requiring that > > the init function > > be called immediately before > > Just to be precise, init() is a method on your module. It's not a function. > > > > > S.addAround(DB.buildLoanWrapper) > > > in Boot,scala. > > > But, there is a larger issue at stake here, I fear, and that is that > > true modularization > > requires adherence to rules of encapsulation and complete > > documentation, two things > > that are problematic in Scala code (perhaps due to its power and > > complexity), unlike pure OOP. > > Ummm... as far as I know, Scala is a pure OO language. Everything in Scala > is either the instance of a class (and object, but object is overloaded with > Scala's use of it as a keyword for singleton) or a method. There is nothing > else in Scala. In this way, Scala is like Smalltalk and Ruby. It's not > like Java where things exist in Java that are neither an instance nor a > method (static methods, primitive types, etc.) > > There is nothing that we can't do in Scala to encapsulate anything... the > issue that I see is "what do you want to encapsulate?" > > > > > When I've written before on this subject in this group, I've gotten a > > lot of examples in the small > > purporting to dispute my contention, but falling short. If you know > > I'm wrong, fine ... let's see it. > > If you just think I am, well...think harder. > > Let's separate Lift from Scala the language for a moment. I'm no expert in > PLT so I'm not going to argue encapsulation in Scala. > > I can argue about Lift's modularization and what its limitations are. > > The following things in Lift I know to be non-modular: > > - Mapper: because one cannot subclass Mapper definitions, it's not really > modular. Yes, I've built (and subclassed) ProtoUser, but it's a huge hack > and anything serious (e.g., subclassing an existing mapper and *changing* > the behavior of one on the fields) is not doable with Mapper. This is > basically because I've never meant Mapper to be a serious OR mapping tool, > but more of an ActiveRecord clone where you can create a mapping between an > RDBMS and some sort of "record". I use Mapper very successfully, but it's > not meant for the same things OO is meant for (subclassing) or what Mixins > are meant for. > - SiteMap: SiteMap is frozen at boot time. This means that OSGi modules > can't load and unload themselves and mutate the sitemap. Because the > sitemap is fixed at boot time, it's also not possible for a module to > insert > menu items at an "appropriate" place in the menu hierarchy. > - LiftRules: like SiteMap, the LiftRules are fixed at boot time. It's > not possible for modules to load/unload dynamically and change the various > PFs dynamically. > > I have a plan for fixing the LiftRules stuff so we can fully support OSGi > modules. I will likely extend that to supporting more dynamic sitemaps. > > More broadly, every time I've had Scala code that's "concrete" and needed to > be made more runtime dynamic, the process has been simple, quick, and > painless. Breaking classes into traits and composing those traits into > different runtime configurations has by and large been a few minute to few > hour project. Yeah, it may be considered "poor mans" DI to use traits and > the cake pattern, but I find that the type safety that Scala offers makes > the small extract Scala coding effort to be worth it vs. writing more > tests/configuring more runtime stuff/the weird errors that creep into the > code despite tests. > > > > > This is not small potatoes There are plenty of languages on the dust > > heap precisely because > > of the extension problem. > > Can you be very detailed about what kind of problems you're seeing. Maybe > the folks on this list can help you work through them and maybe we'll all > discover new Scala patterns. > > Thanks, > > David > > > > > > > Glenn... > > > On Aug 26, 2:53 pm, David Pollak <feeder.of.the.be...@gmail.com> > > wrote: > > > On Wed, Aug 26, 2009 at 10:13 AM, glenn <gl...@exmbly.com> wrote: > > > > > Timothy, > > > > > I'm still not convinced that Lift applications can be modularized as > > > > simply as you suggest. > > > > Do you have any samples of your MyLib.init? How do you handle the non- > > > > PF's, like schemify and setSiteMap? > > > > I typically return my menu items from my init function. You can call > > > schemifier from within your init function. > > > > > As for templates, I've learned that you can use the templating > > > > mechanism in Loc to eliminate the need for > > > > html files, but that's only a small part of the problem. > > > > > Glenn... > > > > > On Jul 27, 4:01 pm, Timothy Perrett <timo...@getintheloop.eu> wrote: > > > > > Hi Glen... > > > > > > I actually do a lot of this - we have a product at work and i've just > > > > > written a bunch of abstractions for work which just require me to do: > > > > > > MyLib.init > > > > > > In the boot file of a new application and then everything wires up - > > I > > > > > couldn't think of anything more straightforward? > > > > > > The vast majority of stuff in lift is done with PF's, so you can > > > > > pretty much just write them in external jars, and import them - my > > 3rd > > > > > part stuff usually has a lift-webkit dependency so that I can just do > > > > > the LiftRules.disptach.append stuff directly in the init method, but > > > > > its really no biggy and saves boilerplate. > > > > > > So given your example, this scheme should work right? > > > > > > Cheers, Tim > > > > > > On Jul 27, 11:52 pm, glenn <gl...@exmbly.com> wrote: > > > > > > > I'm interested in abstracting out useful features from my Lift > > > > > > applications for ease of reuse, but I haven't found an easy way to > > do > > > > > > it. I find myself creating a new Lift aplication for each feature, > > > > > > with all the baggage (bootstrapping, etc.), and I then have to do a > > > > > > lot of code modification to the application I'm adding the feature > > to > > > > > > in order to get it to work. > > > > > > > For example, suppose I want to add role-based user login to an > > > > > > application that already has a User model just by dropping in a jar > > > > > > file with the new feature. I don't see how to do it without some > > > > > > boostrapping modifications. > > > > > > > Has anyone really tried to modularize their Lift development. I'd > > be > > > > > > very interested in some suggestions. > > > > -- > > > Lift, the simply functional web frameworkhttp://liftweb.net > > > Beginning Scalahttp://www.apress.com/book/view/1430219890 > > > Follow me:http://twitter.com/dpp > > > Git some:http://github.com/dpp > > -- > Lift, the simply functional web frameworkhttp://liftweb.net > Beginning Scalahttp://www.apress.com/book/view/1430219890 > Follow me:http://twitter.com/dpp > Git some:http://github.com/dpp --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---