Version 24 of rename

Updated 2015-01-04 23:49:08 by aspect

The documentation for the [rename] command, used to rename Tcl commands (such as procs, widgets, objects and coroutines), is available at http://www.tcl.tk/man/tcl/TclCmd/rename.htm .

The [rename] command is most often used for wrapping commands. In other words, the programmer uses [rename] to hide another command -- so that a wrapper can be placed around the hidden command to change its behavior. Examples of this important concept abound on the Wiki; among the clearest are: DGP: Be aware that if you rename a command into another

[Discuss examples. Explain errorInfo subtleties (refer to live examples). Explain "return [eval ::_$original_command \$first_argument $args]" idiom.]

RS Another frequent application for rename is to remove commands, by renaming them to the empty string:

 rename foo {}

Rename and Namespaces

DGP Be aware that if you [rename] a command into another

  % namespace eval one {
    variable message "I'm in one"
    proc test {} {variable message; return $message}
  }
  % namespace eval two {variable message "I'm in two"}
  % rename one::test two::test
  % two::test
  I'm in two

aspect: Also watch out for where you're renaming commands to: aspect Also watch out for where you're renaming commands to:

  % proc foo args {}
  % namespace eval ddd {namespace which -command foo}
  ::foo
  % namespace eval ddd {rename foo foo}
  % namespace eval ddd {namespace which -command foo}
  ::ddd::foo

Rename and the empty string

Lars H: If you really want to rename a command to have the empty string as name, then include the namespace to make the rename argument nonempty:

 % proc foo {} {return 1}
 % foo
 1
 % {}
 invalid command name ""
 % rename foo ::
 % {}
 1

MTayel - 2010-01-24 10:56:48 HaO 2010-04-10: (discussion on CLT ): rename or delete from inside targeted proc is allowed: Here's a funny thing about Tcl and the rename command, the rename command help states that "SYNOPSIS:rename oldName newName" and "if newName is an empty string then oldName is deleted", here's the funny part, in Tcl you can create a Proc called {}, i.e. the proc itself is an empty string, try the following code:

proc ::runOnceAndDelete {} {
% proc {} {} {
     puts Aloha
  }
% {}
Aloha

the result is Aloha printed on your screen, now try this:

% rename {} {}
% {}
ERROR ambiguous command name "": ...

This is very understandable (the rename logic is simple: if newName is an empty string delete oldName), but what if I really want to rename my proc to an empty string?!!, i.e. if I have a proc called putsAloha that I want to rename to {}?!!!, of course this is whole thing is ridiculous, all I'm getting at is the fact that the rename command is not very modular, and changing it will destroy backward compatibility, solution to this might be a "rename2" and "delproc" commands and deprecating old "rename", again, these are very ridiculous concerns I'm only talking about the modularity of Tcl.

AMG: See suggestion #1 on Tcl 9.0 WishList. Search for "insane". :^)


Rename and clobbering existing commands

GDE What's the recommended way to test for the pre-existence of the "destination" argument proc to avoid an error at runtime? The best I could come up with is:

  if {![llength [info commands new_proc_name]]} {
    rename old_proc_name new_proc_name
  }

MJ - The way to avoid the error is to use [catch], this is in line with the view that you shouldn't check if you can do something, but just do it (and handle errors):

 if {[catch {rename old new}]} {
    # handle error because new already exists
 }   

GDE What if I actually do care about the error? In other words, I don't want to do the rename if I've already done it?

(By way of context: this is in a script that may repeatedly get sourced into a single interpreter during a debug session. The first rename creates a backup of the "production" version of the proc then the rest of the script redefines a wrapper around that production version. The user may then edit the debug script to further refine the wrapper proc and re-source, but the catch method will then create a wrapper around the wrapper around the original, rather than just redefining the first wrapper.)

slebetman: No worries, rename won't let you do it and will generate an error. Use catch to prevent that error from halting your program and possibly do something if it happens (see MJ's example above).

GDE Ahh, right, I've got it now - for some reason I thought the catch forced the operation, instead of failing "silently" (but detectably).


Renaming a proc from within

HaO 2010-04-10 ([discussion on CLT ]): rename or delete from inside targeted proc is allowed:

    # do something
    rename ::runOnceAndDelete ""
}