Stata的一个有时不方便的功能是调用一个未定义的宏会返回缺失值.
[ edit:Stata实际上会返回一个缺少的字符串""
,而不是数字丢失值],而不是抛出错误。
如果宏名称拼写错误,那么正确执行需要宏定义的一段代码可能只会运行给出错误的结果。
例如:已定义
global $options = , vce(robust)
,何时
之后一个人写了reg y x $opt
而不是reg y x $options
程序运行,可能很难意识到vce()
选项没有被考虑。
有没有办法强制Stata在这种情况下发出错误,或者是否有一些有用的技巧/最佳实践可用于降低引发此类错误的风险?
答案 0 :(得分:2)
该功能描述不正确。未定义的宏被评估为空字符串,通常写为""
,即分隔符" "
不包含任何内容,或者 - 如果您愿意 - 它们之间不包含任何内容。
未定义的宏不会被评估为数字系统缺失,写为句点.
(如果需要,可将其称为点或停止)。
如果将宏设置为包含系统缺失的其他内容,则会看到系统丢失,这完全不同。例如,程序保存的结果可能是系统缺失。
理解这一点的一种方法是Stata中的宏包含字符串,而不是数值;一些宏具有数字解释的事实是另一回事。因此,未定义的宏被计算为空字符串。
Stata程序员学会建设性地使用此功能,作为在未定义宏时允许默认值的方法以及定义宏时的其他选择。
你是正确的,该功能是一个错误的来源,因为当拼写错误导致Stata看到一个名字没有定义,只是忽略了引用。这个bug仍然是程序员的错误,而不是Stata的错误。
那么,除了像往常一样检查代码之外,你能做些什么呢?您始终可以检查是否已定义宏,如
if "$options" == "" {
* do something
}
else {
* do something else
}
相反,
if "$options" != ""
是对内容的测试。
或者,您可以使用字符串标量。这是一个实验:
. sysuse auto, clear
(1978 Automobile Data)
. scalar foo = ", meanonly"
. summarize mpg `=scalar(foo)'
. ret li
scalars:
r(N) = 74
r(sum_w) = 74
r(sum) = 1576
r(mean) = 21.2972972972973
r(min) = 12
r(max) = 41
. summarize mpg `=scalar(bar)'
bar not found
Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
mpg | 74 21.2973 5.785503 12 41
在这种情况下,当引用未定义的标量时出现错误消息,但命令以任何方式执行。
就个人而言,作为一个长期(1991-)和高强度的Stata用户,我只是常规地使用宏,并且认为偶尔会被这种类型的错误所困,这是一个非常小的代价。在尝试回答这个问题之前,我从未使用过这种意义上的字符串标量。
这是一个不同的论点,但我认为以这种方式使用全局宏作为糟糕的编程风格。对于最小化全球声明实体的使用,编程中存在一般性争论。本地宏是首选的野兽。