1

很多时候,我试图定义一个宏只是为了发现它没有被创建。

  • 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
4

2 回答 2

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'"

您需要使用 评估算术运算=。在引用 local 时,您也缺少引号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'" != ""
于 2014-09-22T18:02:27.583 回答
3

罗伯托给出了一个很好的详细答案,但另外让我们在这里尝试一个概述。关键是你对失败的理解以及 Stata 是否同意你的看法。

就 Stata 而言,清除现有的本地宏并将空字符串分配给(潜在的)本地宏名称具有相同的效果。如果我走

local foo = 42 
local foo 

或者

local bar 

过程不同,但最终结果是相似的。在第一种情况下,本地命名foo消失,第二种情况本地宏bar永远不会创建。第二种情况并非徒劳,因为(例如)程序员经常想明确本地宏最初是空的(除非这不太可能),或者删除任何以前创建的具有该名称的宏。

更简洁地说,至少就用户而言,Stata 不区分空(本地或全局)宏和不存在的宏。如果您将这里的定义理解为受操作系统外壳而不是字符串处理语言的启发,这就不那么奇怪了。

但是有一个有用的结果。考试

if "`bar'" != "" 

既是对存在性的检验,也是对本地宏的非空性的检验bar,它也适用于带有数字字符的宏。

此外,在某些情况下,您可能会尝试将非空字符串放入宏中,就您而言犯了一些错误,并以分配一个空字符串结束。这可能是一个编程错误,但就 Stata 而言,这并不违法,正如上面的示例已经暗示的那样。

完整性在这里是难以捉摸的,但另一种情况是宏定义可能由于其他原因是非法的。因此

local foo = lg(42)

将失败,因为没有功能lg()。另一方面,

local foo lg(42) 

就 Stata 而言将成功,因为没有强制执行评估,因此 Stata 永远不必解决lg(42)。宏将只包含lg(42)文本。

于 2014-09-22T19:56:09.293 回答