gpt4 book ai didi

dynamic - 如何在运行时动态修改 proc 主体?

转载 作者:行者123 更新时间:2023-12-02 08:35:49 34 4
gpt4 key购买 nike

原则上我想做这样的事情:

#grab some value from outer source (i.e. file or list defined by another programer)
set original_proc_name foo

#define function with a specific name using the string from that outer source
proc "helper_[set original_proc_name]" {val} {
#I need to use that string inside the body of the new proc
return [[set original_proc_name] $val]
}

我基本上需要神奇地控制 proc 主体,就好像它是 [list 一样。 . .]

有没有办法在运行时动态定义过程体?

我想这样做是因为我需要定义一堆用于测试的过程,这些过程基本上会简单地调用一堆由其他程序员编写的具有特定参数的过程。

为什么要定义新的过程?因为那是我们设置的回归期望看到的(要运行的过程的名称)。

最佳答案

在 Tcl 中,没有什么是特别神圣的。您可以将语言中的任何内容与几乎任何其他内容一起使用。特别是,您可以使用任何字符串生成命令(实际上所有这些命令,尽管有些只生成空字符串)来生成过程的主体; proc 只是一个普通的 Tcl 命令(它恰好生成其他 Tcl 命令,尽管也有其他命令这样做)。

在您的具体情况下,您最好使用不同的方法。

set original_proc_name foo

interp alias {} helper_$original_proc_name {} apply {{cmd val} {
$cmd $val
}} $original_proc_name

好吧,这看起来有点神奇。这不是真的。让我们由内而外地工作。

apply 是一个像无名程序一样有效工作的命令。它的第一个参数是一个列表(通常有两个元素),它定义了“类似过程”的东西和主体的参数。它的后续参数是实际参数。因此,

apply {{a b} {
puts "a=$a and b=$b"
}} 123 456

将打印 a=123 and b=456 。我们将它与一个特定的主体一起使用,该主体接受两个参数并将一个参数应用于另一个参数;第一个参数是命令名称(大概),第二个参数是发送到该命令的值。所以我们开始:

apply {{cmd val} {
$cmd $val
}} puts "Hi"

我们确实得到了一段非常普通的代码。好处在哪里?

好吧,我们在这里使用 interp alias。这种特殊形式:

interp alias {} foo {} bar boo

使得当您使用 foo 作为命令时,Tcl 将调用交给 bar boo ,附加到 foo 的任何额外参数。在一个简单的例子中:

interp alias {} writeError {} puts stderr

给我们一个命令,它将像这样将消息写入 stderr:

writeError "GRUMPY CAT WANTS NO PART OF THIS!"

好的,所以我们将这两件事放在一起。

interp alias {} helper_$original_proc_name {} apply {{cmd val} {
$cmd $val
}} $original_proc_name

在这里,我们正在制作的命令别名是通过字符串替换生成的,我们正在对内部简单调用程序进行部分应用,以便它被锁定为原始命令名称。结果是我们使 helper_foo 成为一个只接受一个参数的命令,并将该参数传递给原始 foo 进行处理。

所有这些都没有复杂的字符串替换。

这种情况可能有点矫枉过正,但对于更复杂的任务来说,它比生成正确的脚本要简单得多。它也比这个稍微矫枉过正,我会在自己的代码中使用它:

interp alias {} helper_$original_proc_name {} $original_proc_name

但这有微妙不同的语义。


在 Tcl 8.6 中,您还有 tailcall 。这可以使事情变得更加“有趣”。权力越大,不负责任的机会越大……

关于dynamic - 如何在运行时动态修改 proc 主体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21736934/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com