Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有处理命名参数的Tcl包/加载项?_Tcl_Parameter Passing - Fatal编程技术网

是否有处理命名参数的Tcl包/加载项?

是否有处理命名参数的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

在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 \"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上有一整页讨论命名参数:

你可以自己创造一点。有几种机制允许您执行此操作:

  • 进程可以定义其他进程
  • proc的行为就像proc(函数定义系统不是语法,而是函数调用)
  • procs可以使用
    args
    参数而不是位置参数,并手动处理参数列表
  • 您可以使用
    uplevel
  • 您可以使用
    upvar
  • 一切都是一根弦 等等

    我不确定我是否列出了所有可能的机制

    我个人对这一想法的实施是optproc:

    实现本身非常简单:

    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
    并在循环中声明每个局部变量

  • 这是一个元解决方案。我没有处理args,而是创建了另一个函数(语法)来创建一个处理args的函数

  • 用法(从Donald的答案中盗取)为:

    optproc example {abc def} {
        puts "abc=$abc, def=$def"
    }
    

    但请注意,我的解决方案不是唯一的解决方案。有很多方法可以做到这一点,但仅限于创造性。

    我认为wiki上有一些代码可以做到这一点,但我认为,如果需要命名参数来为参数处理添加更多规则,我们大多数人都会觉得使用dict或数组太方便了。数组也可以工作<代码>数组集首先是默认值,然后是
    数组集
    实际参数。在
    的末尾有一个额外的
    ]
    放置“abc=$abc,def=$def”]
    (编辑需要有6个字符…)