> I want to make web programmer's life easy. I want she just *uses* what she > needs, without caring about *loading* it. Of course, this is the ideal case, > and > I'm trying to achieve that stepwise. > > Let's assume there are db facilities in a ::Db namespace. The framework itself > doesn't need them to work, so it doesn't load them in order to save time and > memory. > > Soon or later, after the framework is ready, a user code will be run depending > on the request. Let's suppose that code *needs* the db stuff, so there could > be > a line such > > Db::query "sql query" > > Here, Db::query is not known, the ::unknown proc will be called, and there > magic > happens: the framework-provided ::unknown finds that Db is a known subsystem, > it finds the right file containing it, it sources that file, making > the Db namespace available; then it could call some initializing proc, such as > ::Db::init, and finally, it retries the Db::query call.
You should have led with this in your initial inquiry. :) The problem with asking, "how do I do X" instead of "I'm trying to do X, what is the best way" is that sometimes your question gets answered without actually giving the RIGHT answer. In this case, Tcl already does what you want. It's called auto_load. Rivet already uses it for all of the commands in the rivet-tcl directory like parray and such. Those bits of code are not loaded with each interpreter, they are only sourced in the first time you attempt to use them. You can find the docs here: http://www.tcl.tk/man/tcl8.6/TclCmd/library.htm You don't need to reinvent what Tcl already does here. In fact, Tcl itself uses the auto_load capabilities for a lot of things. Open up tclsh and parray the ::auto_index array. You'll find a bunch of stuff in there. All that being said, it may be a better idea to be explicit. Instead of auto-loading the DB code the first time the call is made, you make the developer add: package require framework::db to get the DB package loaded. Whether or not you do it explicitly or magically is purely up to you. Some would argue for either way, and I don't have a specific opinion. Just pointing it out. 0-] Also, just to note, before you go renaming ::unknown out of the way, you should read up on the [namespace unknown] command. You can actually specify your own unknown handler for every single namespace in Tcl and then let them roll back to a higher-level handler or eventually down to ::unknown itself. Check the namespace docs. >> I probably should do something like I've just suggested to you and open up >> my work >> for everyone to criticize it > > It would be very nice, expecially to see other implementations in the > area of security and user input handling. > >> My hope is simple, that we can end up having something flexible and light >> enough >> to be easily stretched to be reused in the many cases where one needs to >> create a web interface to some application. > > Definitely agree, it is a strong requirement for making Tcl compete with other > solutions and increase its usage base. I'm sure you'll find nearly everyone on this list has written a Tcl / Rivet framework of some kind at some point, myself included. I have a really nice little framework I use for my web apps, but I've never shared or released it because I don't want to support it / update it for a bunch of other people. That said, I will offer a few notes before you tilt at this windmill. 0-] 1. Don't worry about objects. Everyone loves OOP, that's cool, but you don't need it here. At least not a parent, singleton object for each request. You already have that, it's called the ::request namespace. Rivet builds it, executes in it, and destroys it with every request. Creating an object on top of that just to run your framework is overkill. 2. Like you've already decided, keep the bits separate. I have the main framework, a DB package and a UI package (for forms and other bits of web UI sundry) all in packages that you can choose to use or not choose to use. Cuts way down on load times. 3. Initialize your framework in the global namespace one time using the package mechanism, then you don't have to incur that cost with each request. ESPECIALLY in production code. I built a debug variable in which says that I'm in a "dev" instance of the framework, and in dev mode the entire framework is reloaded with each request. This is for me when I'm developing the framework and other bits. I want to reload each time to make sure my changes are in. That's all I can think of in a few minutes. 0-] Damon --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
