是否有处理命名参数的Tcl包/加载项?
在Python、Ruby 2.0、Perl 6和一些硬件描述语言中,可以使用命名参数。看这个。这使代码更具可读性,更易于维护,等等。在TCL 8.6中,除了使用字典作为解决方法外,还有其他方法可以完成/扩展吗?在8.6中,使用从是否有处理命名参数的Tcl包/加载项?,tcl,parameter-passing,Tcl,Parameter Passing,在Python、Ruby 2.0、Perl 6和一些硬件描述语言中,可以使用命名参数。看这个。这使代码更具可读性,更易于维护,等等。在TCL 8.6中,除了使用字典作为解决方法外,还有其他方法可以完成/扩展吗?在8.6中,使用从args解析的字典。dict merge命令可以帮助: proc example args { if {[llength $args] % 2} { return -code error "wrong # args: should be \"exa
args
解析的字典。dict merge
命令可以帮助:
proc example args {
if {[llength $args] % 2} {
return -code error "wrong # args: should be \"example ?-abc abc? ?-def def?\""
}
set defaults {
-abc 123
-def 456
}
set args [dict merge $defaults $args]
set abc [dict get $args -abc]
set def [dict get $args -def]
puts "abc=$abc, def=$def"
}
example; # abc=123, def=456
example -abc 789; # abc=789, def=456
example -def 789; # abc=123, def=789
example -def 246 -abc 135; # abc=135, def=246
通过验证,您可以更进一步(使用tcl::prefix
命令可能会有所帮助),但这需要做更多的工作,并且在生产代码中不会为您带来更多的好处。但事实并非如此
有两个建议可以添加完整命名的参数处理
(,)到目前的8.7,但我不确定两者是否真的获得了牵引力。(从我的角度来看,问题是,不自愿支持命名参数的代码必须承担额外的运行时成本。可能还有其他问题,例如对首选语法的分歧;我没有太多关注这一点,因为我仍然在为一段相当热门的代码的性能影响而烦恼。)tcler的wiki上有一整页讨论命名参数: 你可以自己创造一点。有几种机制允许您执行此操作:
args
参数而不是位置参数,并手动处理参数列表uplevel
upvar
proc optproc {name args script} {
proc $name args [
string map [list ARGS $args SCRIPT $script] {
foreach var {ARGS} {
set [lindex $var 0] [lindex $var 1]
}
foreach {var val} $args {
set [string trim $var -] $val
}
SCRIPT
}
]
}
我基本上使用字符串操作(stringmap
)直接将函数体($script
)插入到定义的函数中,而不进行任何替换等。这是为了避免处理任何$
或[]
。有很多方法可以做到这一点,但我的go-to工具是string-map
这与Donald的答案相似,只是有两点不同:
args
转换为dict
,而是手动处理args
并在循环中声明每个局部变量optproc example {abc def} {
puts "abc=$abc, def=$def"
}
但请注意,我的解决方案不是唯一的解决方案。有很多方法可以做到这一点,但仅限于创造性。我认为wiki上有一些代码可以做到这一点,但我认为,如果需要命名参数来为参数处理添加更多规则,我们大多数人都会觉得使用dict或数组太方便了。数组也可以工作<代码>数组集首先是默认值,然后是
数组集
实际参数。在的末尾有一个额外的]
放置“abc=$abc,def=$def”]
(编辑需要有6个字符…)