在TCL是有可能有参数的默认值是一个函数调用的返回值?
proc GetParameterValue { } {
# calculation for value...
return value
}
proc TestFunction { {paramVal [GetParameterValue]} } {
puts $paramVal
}
TestFunction
这导致印刷“[GetParameterValue]”。而不是调用程序GetParameterValue。这是可能在TCL做或做我需要重新设计的代码这一点吗?
参数的默认值只能是你在计算过程中声明的时间常数(最常见的,它们是文字,这意味着你不需要使用list
做建筑):
proc TestFunction [list [list paramVal [GetParameterValue]]] {
...
}
为了计算在程序调用时的默认值,你必须计算移动到过程的主体。有几个方法可以做到的是否做计算的检测,但它们归结为三个选项:使用标记值,让字的计数呼叫,并采取分析的完全控制。
诀窍这是为了找到一些价值是真的不太可能被通过。例如,如果这是要显示给用户一段文字,什么也没有,但在它的ASCII码NULL值是不会发生;提出,在默认情况下,你可以告诉你是否已经得到了默认,并能与复杂的代码提供什么替代。
proc TestFunction {{paramVal "\u0000"}} {
if {$paramVal eq "\u0000"} {
set paramVal [GetParameterValue]
}
...
}
这依赖于info level
内省命令的能力。特别是,info level 0
报告的实际参数当前过程的完整列表。计数的一点,我们就可以知道一个真正的价值是否被通过。
proc TestFunction {{paramVal "dummy"}} {
if {[llength [info level 0]] < 2} {
# Note that the command name itself is always present
set paramVal [GetParameterValue]
}
...
}
这是一个完全通用的方法,所以没有什么地方的人提供了一个意想不到的边缘情况的情况下担心,但是当你有多个参数,你需要找出许多参数应该如何存在等自己它更复杂。这就是在这种情况下,简单的,但你有更多的论据变得越来越困难。
最后,你还可以决定做出,它利用它的参数解析的完全控制的过程。你这样做,给它一个参数,args
,然后你可以使用任何方法,你要处理的实际参数列表。 (我倾向于不把只在这种情况下,括号中的正式参数列表,但是这只是我自己的风格。)
proc TestFunction args {
if {[llength $args] == 0} {
set paramVal [GetParameterValue]
} elseif {[llength $args] == 1} {
set paramVal [lindex $args 0]
} else {
# IMPORTANT! Let users discover how to use the command!
return -code error -errorcode {TCL WRONGARGS} \
"wrong # args: should be \"TestFunction ?paramVal?\""
}
...
}
这是目前做什么是先进的,例如,有强制性问题之前可选参数的唯一途径。这也是几乎你有什么用C做,如果你那里执行命令,但调整不同的语言。缺点是,它比使用由proc
命令的执行提供了内置的基本观点分析支持代码肯定更多的工作。
这意味着,以补充多纳尔的完整的答案。在过去,我有时使出[subst]
为计算违约的援助:
proc GetParameterValue {} { return computedDefault }
proc TestFunction {{paramVal [GetParameterValue]}} {
puts [subst -novariables $paramVal]
}
TestFunction; # returns "computedDefault"
TestFunction "providedValue"
TestFunction {$test}
这避免了(实现)参数上完全控制的需要,并捎带到内置参数处理程序。它还允许使用匿名特效,而不是明确指定的那些计算的默认值:
proc TestFunction {{paramVal "[apply {{} { return computedValue }}]"}} {
puts [subst -novariables ${paramVal}]
}
TestFunction; # returns "computedDefault"
TestFunction "providedValue"
TestFunction {$test}
不用说,也有一些假设的背后,它变成取决于一个人的应用案例重要的限制:
[subst]
。看:
TestFunction {[xxx]}
投
invalid command name "xxx"
并且必须消毒,以
TestFunction {\[xxx\]}