'''[MS] This page deals with deep Tcl internals.''' Not to be perused immediately after lunch. Very few readers will be interested. Some recent conceptual difficulties with the proper behaviour for command invocations led me to a bit of archeological discovery in search for answers. Why does ''TCL_EVAL_INVOKE'' do what it does? Is it really the correct thing? What should it actually be doing? With the help of 'cvs blame' I reconstructed this history. First the facts, then a section of comments and explanations on the special needs for the flag bits that control the behaviour of ''TclEvalObjvInternal'': ''TCL_EVAL_GLOBAL'' and ''TCL_EVAL_INVOKE''. This history looks at Tcl8.4, where it was mainly played. In Tcl8.5 [namespace ensemble] is a new user of ''TCL_EVAL_INVOKE''. Up to 8.4 * ''TCL_EVAL_INVOKE'' is only used for ''interp alias'' calls. * ''TCL_EVAL_GLOBAL'' is used for ''source'', ''history'', ''package'' ---- '''HISTORY''' ''Note: revision numbers refer to the file tclBasic.c'' '''1.65 (starting point)''' * TCL_EVAL_GLOBAL: resolves cmd and runs traces in caller's scope, runs cmd in #0 '''1.66 (2002-07-29)''' In order to fix '''[[Bug 582522]] aliases do not fire exec traces''' [http://sourceforge.net/tracker/index.php?func=detail&aid=582522&group_id=10894&atid=110894] the code for [[interp alias]] is modified to call through the main Tcl invocator: ''TclEvalObjvInternal''. A new flag bit ''TCL_EVAL_NO_TRACEBACK'' is added so that ''AliasObjCmd'' keeps control of the generated error messages. * TCL_EVAL_GLOBAL: no change * TCL_EVAL_NO_REWRITE: same thing, just avoids producing an error message '''1.67 (2002-07-29)''' birth of ''TCL_EVAL_INVOKE'' in place of ''TCL_EVAL_NO_TRACEBACK'', change in invocations: * TCL_EVAL_GLOBAL: no change * TCL_EVAL_INVOKE: resolves cmd in #0, runs unknown and traces in caller's, runs cmd in #0 '''1.75.2.1 (2003-04-25)''' * TCL_EVAL_GLOBAL: resolves cmd in #0, runs unknown and traces in caller's, runs cmd in #0 (same as TCL_EVAL_INVOKE) * TCL_EVAL_INVOKE: no change '''1.75.2.20 (2006-02-28)''' Fix for '''[[Bug 1439836]] TCL_EVAL_GLOBAL vs. [uplevel #0]''' [http://sourceforge.net/tracker/index.php?func=detail&aid=1439836&group_id=10894&atid=110894] * TCL_EVAL_GLOBAL: everything at #0 * TCL_EVAL_INVOKE: no change '''1.75.2.21 (2006-03-21)''' Fix for '''[[Bug 1444291]] [[::unknown]] and alias targets (TCL_EVAL_INVOKE)''' [http://sourceforge.net/tracker/index.php?func=detail&aid=1444291&group_id=10894&atid=110894]. TCL_EVAL_INVOKE ceases to set a #0 context; instead, it selectively changes the namespace of the current context to global. * TCL_EVAL_GLOBAL: no change * TCL_EVAL_INVOKE: changed ns for lookup and unknown processing, restored to caller's for traces and command running. If the traces cause a renewed lookup, the second one proceeds in caller's scope (this is a previously undetected bug, I think). ---- '''COMMENTS''' I think that ''TCL_EVAL_GLOBAL'' has essentially converged to its proper meaning. In order to judge if this is the case for ''TCL_EVAL_INVOKE'' it is necessary to specify what that meaning is. The meaning is ''do whatever is needed for alias invocations'', but that itself is not quite clear. It has at least two independent components: 1. Do not produce an error message 1. Control the lookup and execution environment to do the right thing The first goal is simple enough, the second is not. Aliases are supposed to lookup the command in global scope, but execute it in the caller's scope. '''The simplest correct solution is possibly for the command name to be fully qualified at alias creation time, and to go back to a simple TCL_EVAL_NO_TRACEBACK flag.'''