info default

info default procname arg varname

Procname must be the name of a procedure, and arg must be the name of an argument to that procedure. If arg doesn't have a default value then the command returns 0. Otherwise it returns 1 and places the default value of arg into variable varname.

Discussion

Zarutian 2005-07-03: Why does this subcommand require a varname? It realy should return a list with two elements: the boolean (predicate: this arg of this proc has default value?), and the default value (Empty if the boolean is 0 (false)).

MG 2005-07-03: You can get the effect yourself easily enough yourself with a wrapper proc:

proc defaultList {proc arg} {
    set hasDef [info default $proc $arg valDef]
    return [list $hasDef $valDef]
}

The only problem in that is that the scoping of $proc may differ, between where defaultList is called and where the info default inside it is run. An uplevel would sort that, but then the var would be created in the wrong scope, and we'd have to upvar or uplevel to gain access to it, so it could still obliterate a variable in use already. But, if you wanted it...

proc defaultList2 {proc arg} {
    set hasDef [uplevel info default $proc $arg infoDefaultVariable]
    set valDef [uplevel set infoDefaultVariable]
    uplevel unset -nocomplain infoDefaultVariable
    return [list $hasDef $valDef]
}

And to test:

% proc test {a {b defB}} {puts "a -> $a, b -> $b"}
% defaultList test a
0 {}
% defaultList2 test b
1 defB

Zarutian 2005-07-03: It would be easier the other way around, wouldn't it ;)

Then if you wanted to set a variable with the default value of an arg of an proc:

proc defaultArg {proc arg var} {
    set res [info default $proc $arg]
    upvar $var tmp
    set tmp [lindex $res 1]
    return [lindex $res 0]
}

MG Indeed it would. That was really just to show that you could achieve what you wanted, even with info default working as it does now. Perhaps the built-in implementation could be altered to work how you want, if no variable argument is passed (which currently results in an error), but still work as it does now if the variable is given.

Zarutian: If that you are proposing becomes real then one could use it to get the args of an procedure in an slave interp without triggering a trace (if one has been defined for the variable) in that variable.

This gets me speculating which other built-in commmands in Tcl could be pure-function (binary scan comes to mind).

Lars H 2007-07-03:

A better solution to capturing the proper scope of the proc is to get a fully-qualified name for it, by uplevel 1 namespace which ...:

proc defaultList3 {proc arg} {
    set proc [uplevel 1 [list namespace which -command $proc]]
    list [info default $proc $arg val] $val
}

This won't help when it comes to inspecting a slave interpreter, though.