TIP #283 Version 1.5: Modify Ensemble Command Resolution Behaviour

This is not necessarily the current version of this TIP.


TIP:283
Title:Modify Ensemble Command Resolution Behaviour
Version:$Revision: 1.5 $
Authors: Miguel Sofer <msofer at users dot sourceforge dot net>
Neil Madden <nem at cs dot nott dot ac dot uk>
State:Draft
Type:Project
Tcl-Version:8.5
Vote:Pending
Created:Sunday, 01 October 2006

Abstract

This TIP proposes that an ensemble's unknown handler and -map handler resolve the rewritten command in the ensemble's namespace.

Rationale

Ensembles as proposed in TIP #112 have an unknown handler behaviour that makes it impossible to combine it with the namespace path and namespace unknown features of the ensemble's namespace.

This is because the command returned from the unknown handler is invoked in the ensemble's caller namespace: the only way to ensure that it is called in the ensemble's namespace is by returning a FQ command name. But FQ command names bypass the namespace path and namespace unknown mechanisms. Likewise, the command map specified with the -map option of an ensemble also invokes commands in the caller's namespace rather than the ensemble's namespace.

Proposed Change

This TIP proposes to fix this by changing the man page description of the ensemble unknown handler from:

It is up to the unknown handler to supply all namespace qualifiers if the implementing subcommand is not in the namespace of the caller of the ensemble command.

to:

The implementing subcommand is looked up in the ensemble's namespace using normal command location rules.

The description of the -map option should change from:

When non-empty, this option supplies a dictionary that provides a mapping from subcommand names to a list of prefix words to substitute in place of the ensemble command and subcommand words (in a manner similar to an alias created with interp alias; the words are not reparsed after substitution).

to:

When non-empty, this option supplies a dictionary that provides a mapping from subcommand names to a list of prefix words to substitute in place of the ensemble command and subcommand words (in a manner similar to an alias created with interp alias; the words are not reparsed after substitution). The resulting command is invoked with the original arguments in the namespace of the ensemble.

Compatability

All scripts that followed previous best-practice and placed fully qualified command names in the command map or returned them from the unknown handler will be unaffected by this change. Only ensembles whose behaviour was undefined previously will be influenced, and then strictly in a positive direction.

Reference Implementation and Documentation

[RFE 1577282] (which depends on [Patch 1577278]) provides an implementation, with tests and docs.

Illustration

One commenter asked what the difference would be in the following code:

   namespace eval ens {
       proc foo {} {
           puts "Caller namespace is: [uplevel 1 namespace current]"
           puts "I am [namespace origin foo]"
           puts "I am called as: [lindex [info level 0] 0]"
       }
       namespace export ens
       namespace ensemble create -command ens -map {sub foo}
   }
   namespace eval caller {
       proc foo {} {
           puts "Caller namespace is: [uplevel 1 namespace current]"
           puts "I am [namespace origin foo]"
           puts "I am called as: [lindex [info level 0] 0]"
       }
       namespace import ::ens::ens
       ens sub
   }

Today this returns | Caller namespace is: ::caller | I am ::ens::foo | I am called as: ::ens::foo With this TIP, only the last line would be changed to | I am called as: foo

Remarks

Copyright

This document has been placed in the public domain.


Powered by TclThis is not necessarily the current version of this TIP.

TIP AutoGenerator - written by Donal K. Fellows