Tcl匿名函数

时间:2010-07-13 07:50:56

标签: tcl

关于Tcl的纯粹理论问题。

关注this question我在考虑在Tcl中实现匿名函数的最佳方法是什么。

最终结果应该是允许开发人员将完整的proc作为参数传递给anohter proc:

do_something $data {proc {} {input} {
    puts $input;
}};

类似于javascript的

do_something(data, function (input) {
    alert(input);
});

现在,这自然不会起作用OOTB。我正在考虑这种事情:

proc do_something {data anon_function} {
    anon_run $anon_function $data
}
proc anon_run {proc args} {
    set rand proc_[clock clicks];
    set script [lreplace $proc 1 1 $rand];
    uplevel 1 $script;
    uplevel 1 [concat $rand $args];
    uplevel 1 rename $rand {}; //delete the created proc
}

这很有效。但我希望得到一个更好的模式的建议,因为它不是很优雅,并没有真正使用酷Tcl功能。大多数情况下,我想摆脱手动调用anon_run

1 个答案:

答案 0 :(得分:12)

在Tcl 8.5中,您可以使用apply命令。

proc do_something {data anon_function} {
    apply $anon_function $data
}
do_something $data {{input} {
    puts $input
}}

当然,如果您将回调结构化为命令前缀(推荐!),那么您可以这样做:

proc lambda {arguments body} {
    # We'll do this properly and include the optional namespace
    set ns [uplevel 1 namespace current]
    return [list ::apply [list $arguments $body $ns]]
}

proc do_something {data command} {
    {*}$command $data
}

do_something $data [lambda {input} {
    puts $input
}]

如果您使用的是8.4或之前,则需要code from the Tcler's Wiki作为替代,但请注意,这些解决方案仅在语义上等效(充其量);他们的表现并不相同。