Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: st: Detecting a macro expansion error
From
Nick Cox <[email protected]>
To
[email protected]
Subject
Re: st: Detecting a macro expansion error
Date
Mon, 2 Jan 2012 01:40:52 +0000
Sorry, but you have lost me.
Local macros are Stata entities. Reading them into Mata to compare
them and writing back results to Stata looks unnecessarily roundabout.
I haven't felt a need for that hitherto.
I can't see the logic of your first block of code. Local macro -temp-
is defined as a copy of local macro -str-. This can't fail as it is
legal whether -str- is empty or not, so I can't see the point of
-capture-. I don't see why you think that -capture- suppresses macro
expansion.
As the two macros are now identical, there is no point to testing
whether they are not.
I have a prejudice that delaying macro expansion is almost always
unnecessary, developed at length on Gabi Huiber's blog.
http://enoriver.net/index.php/2011/02/10/delayed-macro-substitution/#comments
The "almost always" is because I don't want to appear dogmatic, but I
can't recall a convincing example. I have seen several very
unconvincing examples, however.
Nick
On Sun, Jan 1, 2012 at 11:29 PM, Matthew White
<[email protected]> wrote:
> Hi Nick,
>
> Thanks for your response; that's a good idea. An empty string actually
> is acceptable, but I realized that I probably just don't want to allow
> the user to pass a macro expansion to the program. Of course, I want
> the user to be able to use macros, but I won't allow delayed macro
> expansions (e.g., using -\-). Supposing the string I'm parsing is
> stored in local `str', my code is:
>
> capture {
> local temp "`str'"
> }
> mata: if (st_local("temp") != st_local("str")) st_local("syntaxerr", "1");;
> if `syntaxerr' {
> * error and exit
> }
>
> The -capture- block is to suppress the macro expansion error message;
> -capture- by itself doesn't seem to do this.
>
> Before I got to this point, I tried writing a Mata function that
> searches for embedded macro expansions in a string and tests them in
> Stata. If the expansion errors, the function errors. Unlike the
> expansion error, the function error can be picked up by -capture-. I
> haven't done much testing of the function, but here it is with an
> example in case there's interest:
>
> mata:
> void function checkstring(string scalar str)
> {
> real scalar match
> string scalar expansion
>
> do {
> match = regexm(str, "(`" + `"[^'"][^']*')"')
> if (match) {
> printf("{txt}Evaluating: {res}%s\n", regexs(0))
> expansion = strrtrim(substr(regexs(0), 2, strlen(regexs(0)) - 2))
> if (substr(expansion, 1, 1) == "=" | substr(expansion, 1, 1) == ":") {
> stata("local test " + expansion)
> }
> else if (substr(expansion, 1, 2) == "++") {
> stata("local ++" + substr(expansion, 3, .))
> stata("local --" + substr(expansion, 3, .))
> }
> else if (substr(expansion, -2, 2) == "++") {
> stata("local ++" + substr(expansion, 1, strlen(expansion) - 2))
> stata("local --" + substr(expansion, 1, strlen(expansion) - 2))
> }
> else if (substr(expansion, 1, 2) == "--") {
> stata("local --" + substr(expansion, 3, .))
> stata("local ++" + substr(expansion, 3, .))
> }
> else if (substr(strrtrim(expansion), -2, 2) == "--") {
> stata("local ++" + substr(expansion, 1, strlen(expansion) - 2))
> stata("local --" + substr(expansion, 1, strlen(expansion) - 2))
> }
>
> str = regexr(str, "`" + `"[^'"][^']*'"', "")
> }
> } while(match)
> }
> end
>
> capture noi mata: checkstring("\`='Hello world")
> di _rc
>
> Best,
> Matt
>
> On Sun, Jan 1, 2012 at 2:26 PM, Nick Cox <[email protected]> wrote:
>> You could try testing whether the expression evaluates to an empty
>> string. The usefulness of that approach depends on whether an empty
>> string is acceptable on other grounds.
>>
>> Nick
>>
>> On Sun, Jan 1, 2012 at 7:04 PM, Matthew White <[email protected]> wrote:
>>
>>> Using Stata 11.2 SE, I'm writing a program that requires me to parse a
>>> string passed to the program. I want the program to exit if the string
>>> contains a macro expansion that results in an error. Currently, Stata
>>> displays an error about the macro expansion without exiting, and then
>>> continues to parse the string and run the program. Generally, I want
>>> to know how I can detect whether a command results in a macro
>>> expansion error. Here's an example of what I mean:
>>>
>>> . display "`='Hello world"
>>> invalid syntax
>>> Hello world
>>>
>>> Here, the macro expansion `=' results in an invalid syntax error, but
>>> -display- is still executed (after `=' evaluates to ""), and there's
>>> no return code (r(198) is not displayed). -capture- doesn't help:
>>>
>>> . capture display "`='Hello world"
>>> invalid syntax
>>>
>>> . display _rc
>>> 0
>>>
>>> Essentially what I'd like is something like -capture- that I can use
>>> to determine whether a command results in a macro expansion error. Any
>>> ideas?
>>>
>> *
>> * For searches and help try:
>> * http://www.stata.com/help.cgi?search
>> * http://www.stata.com/support/statalist/faq
>> * http://www.ats.ucla.edu/stat/stata/
>
>
>
> --
> Matthew White
> Data Coordinator
> Innovations for Poverty Action
> 101 Whitney Avenue, New Haven, CT 06510 USA
> +1 434-305-9861
> www.poverty-action.org
>
> *
> * For searches and help try:
> * http://www.stata.com/help.cgi?search
> * http://www.stata.com/support/statalist/faq
> * http://www.ats.ucla.edu/stat/stata/
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/