## ********************************************************
##
## 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 ] \}
}
## ******************************************************** -PSEHmmm, 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. -pseOf course, both versions suffer from the inability to clone default arguments. An exercise for the next reader?-DGPSure, 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]
}-JCDKF: 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
}
