From: Tom J. <tom...@gm...> - 2010-11-11 00:25:48
|
I think you covered all my complaints about the TIP, which more or less boils down to "good idea but no compelling reason to go into core". That could obviously change for any number of good reasons. The next biggest problem is that these types of systems are usually optimized for a particular application. Traces have hard coded callback points because there are only so many points where callbacks can be run during the setting of a variable, for instance. Callback systems are so optimized that I found a need to develop and use two different systems in one code file. One systems works with object attributes and mostly focuses on data validation. But the other is very similar to the current TIP, with a few additional features, minus any error handling. Here is the main table definition: ( From http://junom.com/gitweb/gitweb.perl?p=query-writer.git;a=blob;f=sql/postgresql/qw-callbacks-create.sql ) create table qw_callbacks ( callback_id integer constraint qcal_callback_id_pk not null constraint qcal_callback_id_pk primary key, object_id varchar(100) constraint qcal_object_id_nn not null constraint qcal_object_id_fk references qw_objects, operation varchar(100) constraint qcal_operation_nn not null constraint qcal_operation_fk references qw_operations, callback_point varchar(100) constraint qcal_callback_point_nn not null constraint qcal_callback_point_fk references qw_callback_points, callback_order integer constraint qcal_callback_order_nn not null constraint qcal_callback_order_df default '1', callback_type varchar(30) constraint qcal_callback_type_nn not null constraint qcal_callback_type_df default 'tcl' constraint qcal_callback_type_fk references qw_callback_types, enabled_p char(1) constraint qcal_enabled_p_nn not null constraint qcal_enabled_p_df default 't' constraint qcal_enabled_p_ck check (enabled_p in ('t','f')), callback text constraint qcal_callback_nn not null, -- without this constraint, there is no way to ensure the order of row select constraint qcal_obj_ord_un unique (object_id,callback_point,operation,callback_order) ); Note that object_id is really an alias for an object type/class but could be the subject. Operation is create/update/delete/etc., helps further partition the list. The callback_point is the "event". You must also specify the order in which the callback will run, this is just a relative order. There is also a code type (tcl, plsql, etc.) But this could just as easily specify a particular environment or method of invoking the callbacks. You can also disable a callback without forgetting what it was. The code to run this is just two procs: one which queries this table at startup and places everything into a shared variable (similar to tsv arrays) which can be shared among interps. The other just evals the list of callbacks. Code at: http://junom.com/gitweb/gitweb.perl?p=query-writer.git;a=blob;f=tcl/query-writer-procs.tcl#l1100 Another example which I use but don't usually think of as a callback system is AOLserver. In fact every request is handled by processing a series of callbacks (including overriding or skipping callbacks (or callback points) for a url which would otherwise match the "Method callback_point url_pattern" hook. tom jackson (The other callback system is at line 374 of the same file) On Wed, Nov 10, 2010 at 10:57 AM, Donald G Porter <don...@ni...> wrote: > > I'm playing catch up on this, so what follows is a collection of my > reactions, not all that well organized. Where others have already > made a point, I've tried not to repeat it (%-substitution bad :D, etc ). > > I was excited to see the title of TIP 379, because I've long wanted > the Tk [event] command to come over to Tcl and generalize in a sensible > way beyond windows. However, reading the proposal, it's clear that's > not what this is about. This is not about events at all, since the > proposed command would not touch or interact with Tcl's event and > notifier systems at all. It's more accurate to describe this as > a switchboard for callbacks I think. > > Since this isn't really about Tcl events, I'd shy away from using > too much "event" language to describe it, to avoid confusion. Likewise > I'd caution against adopting the <Event> or <<Event>> conventions. > And I'd be careful about making use of [interp bgerror] to deal with > handler exceptions. [interp bgerror] really is designed to handle > those exceptions that rise back to the real Tcl event loop, rather than in > some more synchronous setting. The handler command registered with > [interp bgerror] expects to be called from the event loop itself, > in a distinct later iteration of that loop, decoupled from the exception. > Several [interp bgerror] implementations, notably Tk's [::bgerror] command > are blocking commands with (effectively) nested [vwait]s inside. > It's not clear to me that getting stuck hanging in a [hook send] > pending the termination of such a beast is a wise move. FWIW, the closest > thing we have to an "approved" solution for this scenario, is the use > of the magic reporting command [::tclLog]. > > While TIP 379 does not propose a generalization of [event], it does > seem to offer a generalization of [trace]s. Rather than the hardcoded > limited set of subjects (command, variable, stacklevel) and a hardcoded > limited set of "events" (read, write, unset, rename, enter, etc.) the > TIP offers a framework for making callbacks triggered by an unlimited > extensible set of "events" from an unlimited extensible set of subjects. > If the proposal could evolve so that the existing implementation of > traces could be replaced by use of the new framework, that would be a > compelling reason to put this functionality into Tcl itself. > > (I would love, love, Love, LOVE, LOVE!! to make the existing [trace] > implementation go away!) > > The most obvious addition that would be needed to make that happen would be > the ability to register C routine callback handlers, and not limit the > functioning of this proposal entirely to the script level. > > If this idea is pursued, it's possible it would enter Tcl not as a > new [::hook] command but as additions to the existing [::trace] "ensemble". > > The connection between this TIP and traces also suggests a good look at > all the tricky corner cases of traces as issues to confront in the new > facility. (What to do when execution of one handler deletes another > bound to the same event? Whether to arrange rules so that handler > invocation loops get detected and prevented? etc.) > > On the other hand, if that ambition is not forthcoming, then I think > this facility is a better fit for tcllib. The key motivation, as I > understand it, is to make a(nother) good implementation of this common > bit of infrastructure available more widely so fewer people will be > motivated to re-invent their own version. That's one of the missions > tcllib exists to accomplish. > > Having said that, I'll observe, that the "uevent" package is already in > tcllib, and also covers at least some of the same space of functionality, > so we should expect that there will continue to be re-invention of this > wheel even after a "hook" package gets added to tcllib. At least part > of the reason for this is that there really are different "tastes" to > cater to. There's a reason Will didn't just drop this idea and embrace > "uevent" when made aware of it. And there will be reasons why others > don't embrace "hook" when its presence in tcllib is made known as well. > > I see an analogy to OO systems. It's a bit of folk wisdom that any > sufficiently serious programmer working in Tcl long enough will invent > their own OO system. In part this is because Tcl did not offer one. > But in part it is because people really do have different needs and > preferences in what they want from an object system. Likewise, at least > the set of serious Tcl programmers working on the right kind of > applications are likely to re-invent some form of this callback system > as well. I think there are really differences in needs and preferences > for a callback system. So to pick one blessed one to become part of > Tcl itself faces some of the same challenges as TclOO. And the good > first step down that road is making this particular solution available as > a package, and then tcllib is a good way to deploy that package. > > Hey, did I say that longtime Tclers invent their own version of this?! > > Attached is the callback system which has been part of OOMMF for around > 10 years or so now. You won't be able to just run it, since it rests > on a foundation of other OOMMF facilities, but reading the source code > ought to be useful enough. I offer it just to show a few of the other > possibilities in this space, to steal or not steal as you like. > > You will see that in light of my comments above, I've made a number of > the same "mistakes" (calling it an 'event' system even though the event > loop is not engaged; using direct [bgerror] calls to report exceptions). > > Some of the differences from [hook] and some of the other systems mentioned: > > Each handler is an instance of a class, so the way to "unbind" is to > call the destructor of the handler, rather than a [hook forget] using > an "observer" name. Instead the destructor of the observer, calls > the destructor of the handler (which it stores in an instance variable). > > Each handler is allowed to declare itself a member of a list of "groups" > and the [Oc_EventHandler DeleteGroup] command can then clear away related > handlers when some common resource they need goes away. This permits > handler cleanup dependent on more things than just a $subject and an > $observer. > > Each handler is an independent instance of a class, so we avoid the > Tk design flaw of permitting only one binding per tag,event pair, > with the fragile need to join multiple bindings with "+" and all that. > > The level of indirection provided by bindtags in Tk is copied. > > The treatment of return codes by Tk is copied. > > Something like Tk's % substitution is copied, extended by the > conversion of "-foo bar" arguments to [Oc_EventHandler Generate] > to cause %foo to be substituted with "bar". The %object substitution > is built in (though it puts in what [hook] calls the 'subject'). > > Tk's scheme of "make substitutions in a script, then eval" is copied. > > Handler construction offers control over where in the handler list the > new handler should go. > > Handler construction supports an option "-oneshot <boolean>", default > false. > When true, the handler is deleted after its first invocation. > > Starting again today, I think I'd do several things different, but it > is a working system. > > One final comment on [::hook] as it is proposed. For those things > that need well-known names in the system, which I think includes > the events, the subjects, and possibly the observers too, I think > these names ought to be resolved in a way dependent on the value of > [namespace current] so that Tcl's namespace facility can be used > to distinguish names that might conflict. I haven't worked out what > that means in detail, but wanted to get it out there. No need to > invent a separate namespace-ing system for these names when we have > a system to build on. > > -- > | Don Porter Mathematical and Computational Sciences Division | > | don...@ni... Information Technology Laboratory | > | http://math.nist.gov/~DPorter/ NIST | > |______________________________________________________________________| > > ------------------------------------------------------------------------------ > The Next 800 Companies to Lead America's Growth: New Video Whitepaper > David G. Thomson, author of the best-selling book "Blueprint to a > Billion" shares his insights and actions to help propel your > business during the next growth cycle. Listen Now! > http://p.sf.net/sfu/SAP-dev2dev > _______________________________________________ > Tcl-Core mailing list > Tcl...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-core > > |