Локальный макрос Stata не определен

Много раз я пытался определить макрос только для того, чтобы убедиться, что он не был создан.

  • Мой первый вопрос: есть ли лучший способ отслеживать эти сбои, чем вручную набирать 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

person Frank    schedule 22.09.2014    source источник


Ответы (2)


Это работает:

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'" != ""
person Roberto Ferrer    schedule 22.09.2014
comment
Ах, да, забыл кавычки в моем разрезе переменных макроса. Любые советы по мониторингу этих тихих сбоев? - person Frank; 22.09.2014
comment
Спасибо, я привыкну использовать display или assert. Очень жаль, что для такой (концептуально) простой проверки требуется так много кавычек. Интересно, как Stata анализирует все, что следует за word # of. - person Frank; 22.09.2014
comment
Я уже потерял счет количеству раз, когда меня кусали проблемы с цитатами. - person Roberto Ferrer; 22.09.2014

Роберто дал хороший подробный ответ, но в дополнение давайте попробуем обзор здесь. Решающее значение имеет то, что именно вы понимаете под fail и есть ли смысл, в котором Стата может согласиться с вами.

Удаление существующего локального макроса и присвоение пустой строки (потенциальному) имени локального макроса имеет тот же эффект, что и Stata. Если я пойду

local foo = 42 
local foo 

or

local bar 

процесс отличается по своей сути, но конечный результат похож. В первом случае локальный макрос foo исчезает, а во втором случае локальный макрос bar никогда не создается. Второй случай не бесполезен, так как (например) программист часто хочет прояснить, что локальный макрос изначально пуст (за исключением того, что это не совсем возможно) или что любой ранее созданный макрос с таким именем удален.

Короче говоря, Stata не различает, по крайней мере, с точки зрения пользователя, между пустым (локальным или глобальным) макросом и макросом, которого не существует. Это менее странно, если вы понимаете, что приведенные здесь определения вдохновлены оболочками операционной системы, а не языками обработки строк.

Но есть полезное последствие. Тест

if "`bar'" != "" 

является одновременно проверкой существования и проверкой непустоты локального макроса bar, а также применима к макросам с числовыми символами.

Кроме того, могут быть случаи, когда вы пытаетесь поместить непустую строку в макрос, делаете какую-то ошибку и заканчиваете тем, что назначаете пустую строку. Это может быть ошибкой программирования, но это не является незаконным с точки зрения Stata, как уже подразумевают приведенные выше примеры.

Полнота здесь неуловима, но еще один случай заключается в том, что определение макроса может быть недопустимым по другим причинам. Таким образом

local foo = lg(42)

потерпит неудачу, потому что нет функции lg(). С другой стороны,

local foo lg(42) 

будет преуспевать в том, что касается Stata, потому что никакая оценка не применяется, и поэтому Stata никогда не приходится работать lg(42). Макрос будет просто содержать lg(42) в качестве текста.

person Nick Cox    schedule 22.09.2014
comment
Спасибо за продуманное резюме. Stata не нужно считать команду незаконной, чтобы выдать предупреждение о ней. Здесь это означало бы отметить, что local foo my_dumb_attempt имеет символы после foo и при этом присваивает foo пустую строку. Stata вряд ли кажется языком для программистов, поэтому я ожидаю, что в этом отношении будет больше ручного управления. - person Frank; 23.09.2014
comment
Вы смешиваете технические вопросы с более личными или субъективными мнениями, которые могут быть интересны для обсуждения один на один, но не поддаются кратким ответам. Stata — это язык, на котором многие люди с удовольствием программируют, причем в долгосрочной перспективе. Mata — это встроенный язык, который больше похож на представления многих других людей о языке программирования. В обоих языках мало поддержки или предупреждений. Это может быть вопросом само по себе. Ваш конкретный пример local foo my_dumb_attempt совершенно законен; Программисты Stata постоянно используют такое копирование текста в макросы. - person Nick Cox; 23.09.2014
comment
Справедливо. Чтобы уточнить, под my_dumb_attempt я имел в виду один из бесчисленных способов получить пустую строку молча, а не буквально вводить или передавать эту команду. Я с нетерпением жду изучения Маты. - person Frank; 23.09.2014
comment
Хорошо, но текст в обратных кавычках, как правило, воспринимается здесь буквально, и шутливые примеры также в порядке вещей. - person Nick Cox; 23.09.2014