TCL:一个过程 运行 可以在另一个过程中并在没有 upvar 的情况下共享它们之间的所有变量吗?

TCL: can a procedure run inside another procedure and share all vars between them without upvar?

假设我想要:

proc set_valid {} {
    set valid 1
    puts "$printme"
}

proc valid_start {} {
    set valid 0
    set printme "ABC"
    valid_stop
    return valid
}

valid_start 会 return 1,没有 upvar 我可以使用它吗?所有变量都将在 proc 之间共享?

我只想用下面的代替,

proc valid_start {} {
    set valid 0
    set printme "ABC"
    ####
    set valid 1
    puts "$printme"
    ####
    return valid
}

只是为了能够重复某些代码行,就像 "source" 对 .tcl 文件所做的那样,但对同一 .tcl 中的特定代码块,我可以这样做吗?

每个过程都有自己的局部变量;要引用调用程序的局部变量,您 必须 使用 upvar (或 uplevel 到 运行 在正确范围内操作它们的命令).

proc set_valid {{printme "the message"}} {
    upvar 1 valid valid
    set valid 1
    puts "$printme"
}

globalvariable 命令非常相似,但(通常)分别用于引用全局变量和当前命名空间变量。

使用该过程定义,您可以执行以下操作:

proc valid_start {} {
    set valid 0
    set printme "ABC"
    # Stuff...

    set_valid $printme

    # I guess you want to return the variable contents, not the name?
    return $valid
}

您也可以通过相同的机制传输 printme 变量(见下文),但我建议将“神奇可用”变量的数量保持在最低限度;如果变量按值发送,按显式传递的名称发送,或在顶部用 globalvariable(在适当的情况下)声明,则它会更清晰、更易于维护。

proc set_valid {} {
    # Emphasising that local variable names are different to the caller's names
    upvar 1 valid abc printme def
    set abc 1
    puts "$def"
}
proc valid_start {} {
    set valid 0
    set printme "ABC"
    # Stuff...
    set_valid
    return $valid
}

如果您希望您的程序像 sourced 那样工作,请使用 uplevel 1.

proc set_valid {} {
    uplevel 1 {
        set valid 1
        puts "$printme"
    }
}

这就是你做类似宏的事情的方式。如果您需要在此进行代码生成,list 命令非常有用。如果您想了解更多信息,请在 Stack Overflow 上提出另一个独立问题。

您可以尝试使用命令 info 和 eval 来了解您要做什么。但从软件工程的角度来看,我不建议这样做,你有点违背了函数的目的

proc proc1 {} {
    set valid 1
}

proc proc2 {} {
    set valid 0
    set code [info body proc1]
    eval $code
    puts $valid
}

proc2