很多时候,我尝试定义一个宏只是为了看它没有被创建。
我的第一个问题是:是否有更好的方法来跟踪这些失败,而不是在我尝试的每个可疑macro list
定义之后手动输入local mylocal ...
?
其次,为什么定义一个本地无声无息?有没有办法为这个事件启用警告?
第三,下面的代码说明了这种行为最近让我感到沮丧的地方:抓住字符串向量中单词的位置;将职位减少一个;并抓住相应(紧接在前)位置的单词。任何指针都会受到欢迎。
。
local cuts 0 15 32 50
local mycut 32
local myposn : list posof "`mycut'" in cuts
// two methods that fail loudly:
local mynewcut : word ``myposn'-1' of cuts
local mynewcut : word `myposn'-1 of cuts
// five methods that fail silently, creating nothing:
local mynewcut : word `=`myposn'-1' of cuts // 1
scalar tmp = `myposn'
local mynewcut : word `=tmp-1' of cuts // 2
scalar tmp2 = tmp -1 // 3
local mynewcut : word `=tmp2' of cuts
local mynewposn = `=`myposn'-1'
local mynewcut : word `mynewposn' of cuts // 4
local mynewcut : word `=`mynewposn'' of cuts // 5
// also fails silently (and is not what I'm looking for):
local mysamecut : word `myposn' of cuts
答案 0 :(得分:3)
这有效:
local cuts 0 15 32 50
local mycut 32
local myposn : list posof "`mycut'" in cuts
local mynewcut : word `=`myposn'-1' of `cuts'
display "`mynewcut'"
您需要使用=
评估算术运算。引用本地cuts
时,您也会错过引号。
尝试使用尚未定义的宏不会被Stata视为错误。这是语言设计的一个要素。另外,请注意(至少)一种不受欢迎的语法
local mynewcut : word `=`myposn'-1' of cuts
并非违法,因此在这些情况下必须小心谨慎。在of
之后,Stata只期待一些字符串,而cuts
则是一个字符串。这样可以正常工作:
local mynewcut : word 2 of cuts cuts2 cuts3
display "`mynewcut'"
但可能不如预期。添加报价时,事情会发生变化。 Stata现在知道它必须进行宏替换操作。
我经常在把它们放入"生产"之前好好看看当地人。但是你可以使用assert
。例如:
local cuts 0 15 32 50
local mycut 32
local myposn : list posof "`mycut'" in cuts
display "`myposn'"
local mynewcut : word `=`myposn'-1' of cuts
display "`mynewcut'"
assert "`mynewcut'" != ""
答案 1 :(得分:3)
Roberto给出了一个很好的详细答案,但另外我们在这里尝试概述。什么是至关重要的正是你理解的失败以及是否有任何意义上的Stata可能会同意你。
消隐现有的本地宏并将空字符串分配给(潜在的)本地宏名称与Stata有关的效果相同。如果我去
local foo = 42
local foo
或
local bar
该过程的种类不同,但最终结果相似。在第一种情况下,名为foo
的本地消失,而第二种情况永远不会创建本地宏bar
。第二种情况并非徒劳,因为(例如)程序员经常想要清楚地知道本地宏最初是空的(除了那不太可能),或者删除任何以前创建的具有该名称的宏。
更简洁地说,至少就用户而言,Stata在空(本地或全局)宏和不存在的宏之间并没有区别。如果您理解这里的定义受操作系统shell的启发而不是字符串处理语言,那就不那么奇怪了。
但是有一个有用的结果。测试
if "`bar'" != ""
既是对存在的测试,又是对本地宏bar
的非空虚性的测试,它也适用于带有数字字符的宏。
此外,在某些情况下,您可能会尝试将非空字符串放入宏中,在您担心时会犯一些错误,并通过分配空字符串来结束。这可能是编程错误,但就Stata而言,它并不违法,因为上面的例子已经暗示了这一点。
完整性在这里是难以捉摸的,但还有一个案例是由于其他原因,宏定义可能是非法的。因此
local foo = lg(42)
将失败,因为没有函数lg()
。另一方面,
local foo lg(42)
就Stata而言,会成功,因为没有评估得到执行,因此Stata永远不会解决lg(42)
。该宏只包含lg(42)
作为文本。