Search code examples
stataverbosity

Stata local macro not defined


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

Solution

  • 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'" != ""