Ticket UUID: | 1886636 | |||
Title: | [clock] inside snit::widgetadaptor | |||
Type: | Bug | Version: | None | |
Submitter: | nobody | Created on: | 2008-02-04 23:06:38 | |
Subsystem: | snit | Assigned To: | duquette | |
Priority: | 6 | Severity: | ||
Status: | Closed | Last Modified: | 2013-07-04 17:26:17 | |
Resolution: | Not Applicable Here | Closed By: | ||
Closed on: | ||||
Description: |
In Tcl 8.5.0 with snit 2.2.1: ---- package require snit snit::widgetadaptor sframe { option -foo[clock format [clock seconds] -format "%Y"] constructor {args} { installhull using frame } } ---- Produces: ---- invalid command name "::tcl::clock::format" ---- | |||
User Comments: |
[email protected] added on 2008-02-06 09:50:47:
Logged In: NO Thanks, Jeff. That does make sense, as it means global scope commands can also be available. I'll take a look at it. Kevin, you're right, it's an odd place to call "clock". I imagine it was intended to set a default option value to a timestamp, which (on the other hand) is a reasonable thing to do. So it really ought to work. kennykb added on 2008-02-06 03:50:38: Logged In: YES user_id=99768 Originator: NO For what it's worth, the list of core commands on which [clock] depends is fairly long (unsurprising for a large module coded in Tcl). I don't want to guarantee that the list will never expand, but I attach the current known dependencies. (On Windows systems, there is also a dependency on 'registry', not shown here.) File Added: commandlist kennykb added on 2008-02-06 03:50:37: File Added - 265175: commandlist kennykb added on 2008-02-06 03:25:27: Logged In: YES user_id=99768 Originator: NO By the way, the way that [clock] command is evaluated in the slave strikes me as a trifle strange. I see: snit::widgetadaptor sframe { option -foo [clock format [clock seconds] -format %Y] constructor args {installhull using frame} } How does that differ in principle from proc foo {} {return bar} snit::widgetadaptor sframe { option -foo [foo] constructor args {installhull using frame} } The second case fails with invalid command name "foo" because, of course, [foo] exists in the master interp and not the compiler interp. In short, it's arguably the widgetadaptor definition that's making the mistake (evaluating arbitrary Tcl code inside the compiler interp) rather than Snit. Is it actually reasonable to expect arbitrary Tcl code to work there? hobbs added on 2008-02-06 03:08:13: Logged In: YES user_id=72656 Originator: NO The patch should be rather self-explanatory. It does all the snit stuff in the same interp in ::snit::compiler instead of in a separate interp. This has benefits and disadvantages, but I think that the benefits may outweigh in the long run. duquette added on 2008-02-05 10:02:56: Logged In: YES user_id=372859 Originator: NO Sorry, Kevin, I don't mean to be difficult. It wasn't clear how you were using proc--I assumed it was just how the code was loaded, rather than being part of a scheme to compile code dynamically. To the extent the core commands place serious restrictions on what you can do with an interpreter without breaking them, those constraints need to be clearly documented. Are they? Jeff, I don't understand what you mean by "turning the snit compiler into a fully namespace-encapsulated solution for 8.5" and "independent namespacing". Are you using a namespace *instead* of an interpreter? Or putting the Snit compilation commands into a namespace *within* the current slave interpreter? I'd like some better notion of what you're doing before I dive into your code. hobbs added on 2008-02-05 09:56:28: File Deleted - 265077: File Added - 265078: namespace-snit.diff Logged In: YES user_id=72656 Originator: NO Update to one that still works with interp method File Added: namespace-snit.diff hobbs added on 2008-02-05 09:54:21: File Deleted - 265076: hobbs added on 2008-02-05 09:54:20: File Added - 265077: namespace-snit.diff Logged In: YES user_id=72656 Originator: NO Updated my patch to correct one. File Added: namespace-snit.diff hobbs added on 2008-02-05 09:53:06: File Added - 265076: namespace-snit.diff Logged In: YES user_id=72656 Originator: NO While not necessarily a short-term solution for this, turning the snit compiler into a fully namespace-encapsulated solution for 8.5 seems possible. It would really depend on what level of importance independent namespacing has for snit. Most of the code I see doesn't rely on that. I just created the following patch that is a first pass at this. It runs our TclApp, VFSE and Inspector from TDK locally with only one change (where we had ::typevariable used in the snit body). I of course don't have full tests for this, so it would need further vetting. It is built so you can switch the modes (from namespace to interp) at 1 point. File Added: namespace-snit.diff kennykb added on 2008-02-05 08:41:53: Logged In: YES user_id=99768 Originator: NO I don't think I can do what you're asking. [clock scan] and [clock format] both work by compiling new Tcl code (defining a proc) every time a new format string is encountered. They rather depend on ::proc being there to do so. (And they suffer dreadfully in performance if they can't compile code.) Also, Snit overloads ::variable, and nearly every procedure in the [clock] implementation begins with one or more [variable] commands. I don't really see how to avoid that one without using fully qualified variable names everywhere and eschewing [variable] entirely. Are you looking to inflict that level of unreadability on core code so that you can overload ::variable? I suspect that what you're really saying here is that you find it unacceptable that every Core command doesn't stand entirely alone -- that some of the Core is written in Tcl, so depends on other pieces of Tcl being there. If you consider it a bug that not all Core commands are written in C, please bring that up on tcl-core, because we're moving more and more to using Tcl for at least some non-critical things. duquette added on 2008-02-05 06:53:20: Logged In: YES user_id=372859 Originator: NO This strikes me as being *not* a Snit bug, but a bug in the new implementation of "clock", etc. Standard Tcl commands, it seems to me, should function normally in any interp, unless excluded for reasons of safety. At the very least, they should be fully defined in a new interp *before* the interp's user starts changing things, rather than being defined lazily. I'm certainly willing to add a fix for this in Snit if it's determined that that's the right thing to do...but I'm not at all sure that it is. kennykb added on 2008-02-05 06:18:14: Logged In: YES user_id=99768 Originator: NO What's going on here is that the 8.5 [clock] command is implemented in Tcl, A number of procedures, including ::tcl::clock::format (the guts of [clock format] are created at run time. The fact that the $compiler interpreter in Comp.Init overlaods ::proc and ::variable means that the Tcl code inside [clock] cannot function normally. A workaround - perhaps a fix, but I don't claim to understand what the compiler is actually doing - is to add the line: $compiler alias clock ::clock to the set of compilation aliases. This will cause all [clock] commands to be evaluated in the master interp, obviating the need to run [clock]'s Tcl code in the slave. This at least got the original poster over the fault in initialization. I would anticipate the same sort of trouble if commands such as [msgcat::*], [package], [auto_load] or [parray] were to be evaluated in the $compiler interp, since they, too, are implemented in Tcl and use [proc] and [variable]. Any thoughts? |