Updated 2011-12-10 08:53:16 by RLE

Believe it or not, I actually needed this for something!
 ## ******************************************************** 
 ##
 ## Name: cloneProc
 ##
 ## Description:
 ## Creates a new procedure identical in behaviour to a
 ## prototype procedure, but with a different name.
 ##
 ## Parameters:
 ##
 ## Usage:
 ##
 ## Comments:
 ##

 proc cloneProc { proto clone } {
      eval proc $clone \{ [ info args $proto ] \} \
                       \{ [ info body $proto ] \}
 }
 ## ******************************************************** 

-PSE

Hmmm, seems like the following is simpler:
 proc cloneProc { proto clone } {
     proc $clone [info args $proto] [info body $proto]
 }

I'm curious why you thought all the extra quoting was needed?

Because I always wear a belt and suspenders. -pse

Of course, both versions suffer from the inability to clone default arguments. An exercise for the next reader?

-DGP

Sure, I'll bite:
 proc cloneProc { proto clone } {
     set argv {}
     foreach x [info args $proto] {
         if {[info default $proto $x y]} {
             set x [list $x $y]
         }
         lappend argv $x
     }
     proc $clone $argv [info body $proto]
 }

-JC

DKF: Woe betide anyone trying to clone anything with a (admittedly bizarre) argument name with a space in with the above code:
  proc cloneProc {proto clone} {
      set argv [list]
      foreach x [info args $proto] {
          if {[info default $proto $x y]} {
              lappend argv [list $x $y]
          } else {
              lappend argv [list $x]
          }
      }
      proc $clone $argv [info body $proto]
  }

(careful Donal, you're about to step on my patent for cloning admittedly bizarre things in space)

MGS [2003/08/12] - I found it a little more complex, dealing with namespaces, etc, so I use:
 proc clone:proc {proc1 proc2} {
 
   set argv {}
 
   set proc [uplevel [list namespace which -command $proc1]]
 
   foreach arg [info args $proc] {
     if { [info default $proc $arg default] } {
       lappend argv [list $arg $default]
     } else {
       lappend argv [list $arg]
     }
   }
 
   uplevel [list proc $proc2 $argv [info body $proc]]
 
   return
 
 }