为什么 Tcl 变量命令总是 return 一个空字符串?
Why is Tcl variable command always return an empty string?
查看下面的代码:
namespace eval foo {
variable bar 5
proc getBar {} {
variable bar
}
proc getRetBar {} {
variable bar
return $bar
}
}
puts "\"[ foo::getBar ]\""
puts "\"[ foo::getRetBar ]\""
exit
它输出:
""
"5"
为什么它不像 set 命令那样 return 变量值?
为什么它总是 return 一个空字符串?如果我想通过过程访问名称空间变量,而不是直接访问它们,那么代码会稍微长一些。不是主要问题,但有点烦人
proc
命令 return 默认为空字符串。调用过程时,过程的 return 值是 return
命令中指定的值。如果过程不执行显式 return
,则其 return 值是过程主体中执行的最后一条命令的值。
这里有趣的部分是 variable
命令从不 return 任何值。它只是 creates/initializes/modifies 一个命名空间变量。
% namespace eval foo {
variable bar 5
proc getBar {} {
variable bar
}
}
如果 variable
命令在 Tcl 过程中执行,它会创建链接到相应命名空间变量的局部变量,因此这些变量由 info vars
.
列出
% info vars foo::*
::foo::bar
% set foo::bar; # Getting the 'bar' value
5
% variable foo::bar 10; # Note that it does not return any value as such.
%
% set foo::bar
10
%
由于过程 getBar
中没有 implicit/explicit return 值,因此 return 是默认的空字符串。
这就是命令的定义方式。这是有道理的,因为如果给定奇数个参数,最后一个是将被声明为命名空间变量但不需要存在的名称。如果它不存在,那么 variable
return 应该是什么值?
不过,编写单命令 getter 过程并不麻烦(假设变量存在):
proc getBar {} {
set [namespace current]::bar
}
或者您可以使用 TclOO 对象(注意您需要 setter 来初始化它):
oo::object create foo
# -> ::foo
oo::objdefine foo variable bar
oo::objdefine foo method setBar v {set bar $v}
oo::objdefine foo method getBar {} {set bar}
foo setBar 5
# -> 5
puts "\"[foo getBar]\""
# => "5"
如果您愿意,可以在一次调用中定义对象:
oo::objdefine foo {
variable bar
method setBar v {set bar $v}
method getBar {} {set bar}
}
之所以如此,是因为这是它的实施和记录方式,也就是说,这是一个相对随意的决定。然而,这是将近 20 年前做出的决定,我们认为没有特别的理由重新审视它。谁知道什么(好吧,可能是非常不明智的)代码会被破坏?
也就是说,variable
的主要用途是使用单个参数。在这种情况下会出现什么结果?它甚至在相关变量不存在时使用:根本不可能有合理的结果,并且与 set
不同,它 而不是 这样做是错误的(它分配一些结构如果需要,在命名空间中,如果在过程中,则绑定一个局部变量)。当我们有四个参数时,您要求的结果也没有什么意义:为什么最后要设置的东西以这种方式享有特权? set
命令拒绝这一点,因此不需要处理哲学后果。
不如让variable
继续做现在做的事情。写一个明确的阅读可能会更长,但是对于代码的 intention 是什么也更加清楚,从长远来看这是一件非常好的事情.
查看下面的代码:
namespace eval foo {
variable bar 5
proc getBar {} {
variable bar
}
proc getRetBar {} {
variable bar
return $bar
}
}
puts "\"[ foo::getBar ]\""
puts "\"[ foo::getRetBar ]\""
exit
它输出:
""
"5"
为什么它不像 set 命令那样 return 变量值? 为什么它总是 return 一个空字符串?如果我想通过过程访问名称空间变量,而不是直接访问它们,那么代码会稍微长一些。不是主要问题,但有点烦人
proc
命令 return 默认为空字符串。调用过程时,过程的 return 值是 return
命令中指定的值。如果过程不执行显式 return
,则其 return 值是过程主体中执行的最后一条命令的值。
这里有趣的部分是 variable
命令从不 return 任何值。它只是 creates/initializes/modifies 一个命名空间变量。
% namespace eval foo {
variable bar 5
proc getBar {} {
variable bar
}
}
如果 variable
命令在 Tcl 过程中执行,它会创建链接到相应命名空间变量的局部变量,因此这些变量由 info vars
.
% info vars foo::*
::foo::bar
% set foo::bar; # Getting the 'bar' value
5
% variable foo::bar 10; # Note that it does not return any value as such.
%
% set foo::bar
10
%
由于过程 getBar
中没有 implicit/explicit return 值,因此 return 是默认的空字符串。
这就是命令的定义方式。这是有道理的,因为如果给定奇数个参数,最后一个是将被声明为命名空间变量但不需要存在的名称。如果它不存在,那么 variable
return 应该是什么值?
不过,编写单命令 getter 过程并不麻烦(假设变量存在):
proc getBar {} {
set [namespace current]::bar
}
或者您可以使用 TclOO 对象(注意您需要 setter 来初始化它):
oo::object create foo
# -> ::foo
oo::objdefine foo variable bar
oo::objdefine foo method setBar v {set bar $v}
oo::objdefine foo method getBar {} {set bar}
foo setBar 5
# -> 5
puts "\"[foo getBar]\""
# => "5"
如果您愿意,可以在一次调用中定义对象:
oo::objdefine foo {
variable bar
method setBar v {set bar $v}
method getBar {} {set bar}
}
之所以如此,是因为这是它的实施和记录方式,也就是说,这是一个相对随意的决定。然而,这是将近 20 年前做出的决定,我们认为没有特别的理由重新审视它。谁知道什么(好吧,可能是非常不明智的)代码会被破坏?
也就是说,variable
的主要用途是使用单个参数。在这种情况下会出现什么结果?它甚至在相关变量不存在时使用:根本不可能有合理的结果,并且与 set
不同,它 而不是 这样做是错误的(它分配一些结构如果需要,在命名空间中,如果在过程中,则绑定一个局部变量)。当我们有四个参数时,您要求的结果也没有什么意义:为什么最后要设置的东西以这种方式享有特权? set
命令拒绝这一点,因此不需要处理哲学后果。
不如让variable
继续做现在做的事情。写一个明确的阅读可能会更长,但是对于代码的 intention 是什么也更加清楚,从长远来看这是一件非常好的事情.