Version 2 of Introspection on aliases

Updated 2003-04-14 14:50:45

Aliases are a powerful concept, but they lack the direct introspection possibilities that are available for procs. For example most of the info subcommands only work on procedures, not on aliases.

Some introspection commands exist, namely the interp subcommands alias, target and aliases.


    # [info args] like proc following an alias recursivly until it reaches
    # the proc it originates from or cannot determine it. 
    # accounts for default parameters set by interp alias
    #
    proc aliasargs {cmd} {
            set orig $cmd

            set defaultargs [list] 

            # loop until error or return occurs
            while {1} {
                # is it a proc already?
                if {[string equal [info procs $cmd] $cmd]} {
                    set result [info args $cmd] 
                    # strip off the interp set default args
                    return [lrange $result [llength $defaultargs] end]
                } 
                # is it a built in or extension command we can get no args for?
                if {![string equal [info commands $cmd] $cmd]} {
                    error "\"$orig\" isn't a procedure"
                }

                # catch bogus cmd names 
                if {[lsearch [interp aliases {}] $cmd]==-1} {
                    error "\"$orig\" isn't a procedure or alias or command" 
                }

                if {[llength [set cmdargs [interp alias {} $cmd]]]>0} {
                    # check if it is aliased in from another interpreter
                    if {[catch {interp target {} $cmd} msg]} {
                        error "Cannot resolve \"$orig\", alias leads to another interpreter."
                    }
                    if {$msg != {} } {
                        error "Not recursing into slave interpreter \"$msg\". \"$orig\" could not be            resolved."
                    }
                    # check if defaults are set for the alias
                    if {[llength $cmdargs]>1} {
                        set cmd [lindex $cmdargs 0]
                        set defaultargs [concat [lrange $cmdargs 1 end] $defaultargs]
                    } else {
                        set cmd $cmdargs
                }
             } 
         }             
     }