什么意思是proc参数是可变的

时间:2015-04-30 12:14:00

标签: tcl

我想知道将变量作为参数是否是正确的语义,如下所示:

proc p1 {$aa} {}

我在tclsh上尝试过,没有任何抱怨,但以下实验失败了:

% set aa bb
bb
% set bb 200
200
% proc p1 {$aa} {puts $bb}
% p1 bb
can't read "bb": no such variable

你看到了什么问题吗?

[更新 - 看到彼得的回答] 我知道upvar语义,谢谢。

我主要的好奇心仍然是使用变量作为proc参数。我知道它并不常见,但是如果语言语法允许的话,它无法帮助我们思考它真正能做些什么。

是的,您的upvar示例正是我想要使用变量作为proc参数进行探索的内容,但到目前为止我的探索告诉我,实际上,我们无法做到这一点,因为" $"被解释为普通的char。

如果我错了,请告诉我。

2 个答案:

答案 0 :(得分:1)

Tcl不支持这样的引用参数:对于Tcl来说,通常的pass-by-reference语义过于静态。相反,命令的逻辑可以通过使用upvar动态地创建参考参数,包括间接参考参数和计算的参考参数,并且还将本地名称重新定位到另一个外部变量。 upvar机制可能看起来很笨拙,但确实非常强大。

(原始答案的(编辑过)遗骸如下:)

这样做的惯常做法是

proc p varName {
    upvar 1 $varName var
    puts $var
}

upvar命令查看另一个堆栈帧(在本例中为1,它是调用者的堆栈帧)并创建一个名为$varName的变量(即变量的名称是{{1}的值在该堆栈帧中,命令堆栈帧中名为“var”的变量引用相同的数据对象。

我不会进一步解释这一点,因为这对提问者没用。

文档:procputsupvar

答案 1 :(得分:0)

有些情况下,从变量提供过程创建调用中的参数是有意义的。主要示例是您动态创建过程的位置,计算要在使用过程中使用的参数。

这实际上是一个不常用的用例!使用起来并不是特别容易。 But I have done it.(好的,这是一个方法调用,但正式参数的语法是共享的。)

该功能的主要原因是它是Tcl的通用语法的一部分。 Tcl非常努力地在解析事物的方式上没有特殊情况(除了命令如何解析传递给它的字符串),这包括在绝大多数其他编程语言中非常特殊的情况,例如:正式参数列表到程序。在Tcl中,这些只是普通值,可以使用任何给出普通值的技术来生成。

将它们放在支架上通常的做法就是如何可靠地操作它并且易于教学。它也 人们想做什么。

所有这些都与Tcl的命令(包括其程序)可以处理可变数量的参数(检查特殊的args参数以及如何指定默认值)以及$aa是的事实无关。本地变量的合法(但奇怪的)名称。