Many times, I attempt to define a macro only to see that it was not created.
My first question is: is there a better way to keep track of these failures than manually typing macro list
after every single dubious local mylocal ...
definition I attempt?
Second, why does defining a local ever fail silently? Is there some way to enable warnings for this event?
Third, the code below illustrates where this behavior frustrated me most recently: grabbing the position of a word in a string vector; decrementing the position by one; and grabbing the word in the corresponding (immediately preceding) position. Any pointers would be welcome.
.
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
This works:
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'"
You need to evaluate the arithmetic operation using =
. You are also missing quotes when referring to local cuts
.
Trying to use a macro that has not been defined is not considered an error by Stata. This is an element of language design. Also, note that (at least) one of your undesired syntaxes
local mynewcut : word `=`myposn'-1' of cuts
is not illegal, so care must be exercised in those cases. After the of
, Stata is only expecting some string and cuts
is consired a string. This will work just fine:
local mynewcut : word 2 of cuts cuts2 cuts3
display "`mynewcut'"
but maybe not as expected. Things change when the quotes are added. Stata now knows it has to do a macro substitution operation.
I usually take a good look at locals before putting them into "production". But you could use assert
. For example:
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'" != ""