格式错误的expr在Tcl中返回空字符串

时间:2014-10-25 02:00:15

标签: tcl expr

这可能听起来很傻。忍受我。在玩expr时,我遇到了以下情况

proc badExpr { a b } { 
    return expr $a+$b
}

proc goodExpr { a b } { 
    return [ expr {$a+$b} ]
}

puts "Bad Expression Result : --->[ badExpr 1 3 ]<-----"
puts "Good Expression Result : [ goodExpr 1 3 ]"

输出:

Bad Expression Result : ---><-----
Good Expression Result : 4

如您所见,proc badExpr返回一个空字符串。出于好奇,我有兴趣知道为什么它会返回一个空字符串?

3 个答案:

答案 0 :(得分:2)

<强>(1)     proc badExpr {a b} {         return expr $ a + $ b     }

在上面的badExpr中,您没有使用TCL expr命令。上面的expr就像任何其他字符串一样处理。如果您确实想使用命令expr,则必须将其放在方括号中。所以它应该是return [expr $a + $b]

return命令返回一个字符串值,您还可以指定各种选项。根据以下http://www.tcl.tk/man/tcl/TclCmd/return.htm的文档,最后一个值是实际的返回结果。

return ?result?
return ?-code code? ?result?
return ?option value ...? ?result?

但是,如果你有任意数量的任意args,它不返回任何东西。我不确定引擎盖下发生了什么,但是当你使用-code或option时,你会得到一个与之相关的值参数。因此,它似乎可能将每对作为选项/值或代码/值处理,并返回最后一个未关联的项目作为结果。

#Returns 3
return 1 2 3 4 3

#Returns nothing
return 1 2 3

<强>(2) expr {$ a + $ b}的工作原因是因为它是proc中的最后一个表达式。我 fa过程不执行显式返回,然后它的返回值是过程正文中执行的最后一个命令的值。并且它不需要是expr {$ a + $ b} ,它可以是你的badExpr中的expr $ a + $ b。

答案 1 :(得分:1)

简而言之,问题是您在调用expr时没有括号。

return expr $a+$b   ;# no worky
return [expr $a+$b] ;# works (but you should have braces around the arguments)

它不是明确地记录,但似乎return接受任意数量的参数。如果参数列表是偶数大小,则该命令返回空字符串。如果参数的数量是奇数,则返回最后一个参数。这与文档一致:正常参数列表包含一个可选的结果值,前面有零个或多个选项名称/值对。它仍然有点出乎意料,因为人们会认为选项名称被限制在有用的名称之内。

哦!如果return是脚本中的最后一个命令,并且它的唯一参数是脚本评估(括号内的代码),则可以始终跳过return(字节编译器无论如何都会消除它)。

proc goodExpr { a b } { 
    return [ expr {$a+$b} ]
}

相同
proc goodExpr { a b } { 
    expr {$a+$b}
}

文档:exprreturn

答案 2 :(得分:1)

有趣的是,badExpr会是这样的:

proc badExpr { a b } { 
    return [expr $a+$b]
}

实际获得的是weirdExpr

proc badExpr { a b } { 
    return expr $a+$b
}

这到底是做什么的?它在结果字典中设置内容。 Tcl结果应该被认为是三件事的三倍:一个结果代码(一个小整数,在这种情况下0表示OK - 1将是抛出错误,而其他几个您通常可以忽略的一个结果值(通常返回的值)和结果字典。结果字典主要用于错误,用于保存堆栈跟踪(用于填充errorInfo全局变量),发生错误的行号,错误的计算机可读描述(用于填充errorCode全局变量)等,但它可以容纳任何旧东西。并且你正在把一些非常奇怪的东西放入其中(因为那是return的工作方式);系统定义的键都以-开头,使它们看起来像普通的选项(字典本身通常被称为选项字典)。

让我们使用catch的双变量形式显示这个(第二个变量捕获字典):

% proc weirdExpr { a b } { 
    return expr $a+$b
}
% catch {weirdExpr 1 3} p q
0
% puts $p
% puts $q
expr 1+3 -code 0 -level 0

是的,那里有一个名为expr的有趣词条,其值为1+3 ...