Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: st: Submitting a command in a couples of pieces


From   Sergiy Radyakin <[email protected]>
To   [email protected]
Subject   Re: st: Submitting a command in a couples of pieces
Date   Thu, 29 Oct 2009 17:00:01 -0400

On Thu, Oct 29, 2009 at 3:20 PM, Martin Weiss <[email protected]> wrote:
>
> <>
>
> "-_request()- will store the result in a local macro if you prefix its name
> with an underscore"
>
> I spent most of the few minutes required for my reply wondering why I could
> not get the -local- -macro- route to work. Now that Bill has pointed out the
> solution, I appreciate that the last example, in [P] on p. 102, does say
> exactly what you are supposed to do to make this work. And yet: Is it not
> highly unusual that the user has to supply the underscore for the -local-?

Martin, why is it unusual?

manual for -display- says:
... _request(macname) ...
we know that the names of local macros all start with an underscore
(check it with -macro dir- after defining some locals and globals)
so to tell Stata whether macname means local or global you put an underscore.

other commands may allow you to do the same. consider for example:
. mata st_global("_mylocal","my local value")
. display "`mylocal'"
my local value

same applies to plugins. In fact plugins do not make a difference, see
the plugins manual: "By macros we mean both global macros and local
macros (local to the program calling the plugin). Internally, global
macros and local macros share the same namespace, with the names of
local macros preceded by an underscore (_). "

I believe this is a rather historical thing. Already in the Stata 5
manual ([R] macro, p.408) we read that:"The command local is formally
defined as equivalent to global _".
And this text survived unchanged to the Stata 11 manual ([P] macro,
p.194). So, if anything, it is the behaviour of the local command that
may be surprising: it does not require an underscore.

Best regards, Sergiy Radyakin



> (I cannot think of another command that requires this treatment). This fact
> could be given more prominence in the manual entry, as normally Stata would
> prepend the underscore for you, as is obvious from:
>
>
> ***
> ma drop _allv
> local a 1
> ma di
> ***
>

*********************************************************************************
In this example, suppose you have:

local a "Local"
global a "Global"

How do you list the value of the local macro a?
Yes:

macro list _a

(or macro dir _a -- not sure why this works as well, but I don't mind,
both are quite intuitive).




>
> HTH
> Martin
>
>
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of William Gould,
> StataCorp LP
> Sent: Donnerstag, 29. Oktober 2009 20:03
> To: [email protected]
> Subject: Re: st: Submitting a command in a couples of pieces
>
> Adrian Sayers <[email protected]> asks,
>
>> [...] i want stata to ask me a question, then i want to key the
>> response, and then i want stata to run a program. It sounds a little
>> pointless but i am trying read in 3000 odd data files plot them and then
>> trim the file to the relevant section.
>>
>> eg.
>>      di "What is the first day of data collection?"
>>      Type 3
>>      di "Day of first data collection = 3"
>>      drop if day<3
>
> Martin Weiss <[email protected]> replied,
>
>> *************
>>      di "What is the first day of data collection?" _request(day)
>>      3
>>      di "Day of first data collection =$day "
>>      drop if day<$day
>> *************
>
> Exactly right.  Let me add a few details.
>
> -_request()- will store the result in a local macro if you prefix its name
> with an underscore, so Martin's answer could have read,
>
>       di "What is the first day of data collection?" _request(_day)
>       3
>       di "Day of first data collection =`day' "
>       drop if day<`day'
>
> Note that I put -_day- in the -_request()-, but even so, after that, I
> referred to -`day'- just as I usually would.
>
> Here's Martin's answer put into a -program-, which might be an ado-file:
>
>
>    program trythis
>        version 11
>
>        di "What is the day of the data collection?  " _request(_day)
>        di "Day of the first data collection = `day'"
>        drop if day<`day'
>    end
>
>
> I next suggest to Adrian that if he is going to ask more than one question,
> he must anticipate that users will sometimes mistype their answers.
> Most commonly, they will hit Return before typing any answer.  As I result,
> I recommend creating a subroutine to get answers:
>
>
>    program trythis
>        version 11
>
>        askquestion "What is the day of the data collection?"
>        local day "`s(answer)'"
>        di "Day of the first data collection = `day'"
>        drop if day<`day'
>    end
>
>
>    program askquestion, sclass
>        args last_line_of_text
>        while (1) {
>                di as txt "`last_line_of_text' -> " _request(_answer)
>                if ("`answer'"=="") {
>                        di as txt "Please answer question, or type" ///
>                           as res "qq" as txt "to break."
>                }
>                else if ("`answer'"=="qq") {
>                        exit 1
>                }
>                else {
>                        sreturn local answer "`answer'"
>                        exit
>                }
>        }
>    end
>
> In the above code, if the user just presses Return, the question is asked
> again.  The user can type -qq- to have the code break (stop asking
> questions).
>
> If I were Adrian, I would also check the lexical class of the answer in
> subroutine -askquestion-.  Sometimes answers can be text, even blank,
> and other times they must be numbers, and even integers.  Adrian needs
> to think about the types of the answers he will need.  As a simple example,
> we might modify -askquestion- to allow the caller to specify one of the
> following lexical types:
>
>                text          (meaning a non-blank string)
>                number        (any number, and only a number)
>                integer       (any number that is an integer)
>
> I would then construct code that looks something like this,
>
>    program askquestion, sclass
>        args lex_class last_line_of_text
>
>        while (1) {
>                sreturn clear
>                askqustion_ask "`last_line_of_text'"
>                local answer  "`s(answer)'"
>
>                if ("`answer'"=="qq") {
>                        exit 1
>                }
>
>                if ("`answer'"!="") {
>                        askquestion_check `lex_class' "`answer'"
>                        if (`"s(invalid)'"=="") {
>                                sreturn local answer "`answer'"
>                                exit
>                        }
>                }
>                else {
>                        di as txt "Please answer question, or type" ///
>                           as res "qq" as txt "to break."
>                }
>        }
>    end
>
>    program askquestion_ask, sclass
>        args text
>        di as txt "`text'" -> " _request(_answer)
>        sreturn local answer "`answer'"
>    end
>
>    program askquestion_check, sclass
>        args lex answer
>
>        if ("`lex'"=="text") {
>                exit
>        }
>
>        if ("`lex'"=="number") {
>                capture confirm number `answer'
>                if (_rc) {
>                        di "You must answer with a number"
>                        sreturn local invalid invalid
>                }
>                exit
>        }
>
>        if "`lex'"=="integer") {
>                capture confirm number `answer'
>                if (_rc) {
>                        di "You must answer with an integer"
>                        sreturn local invalid invalid
>                }
>                exit
>        }
>
>        di as error "Invalid lexical class -`lex'-"
>        di as error "caller has error"
>        exit 198
>    end
>
>
> All that said, there's nothing wrong with Martin's original answer if
> Adrian will only be asking a few questions and asking them of himself.
>
> -- Bill
> [email protected]
> *
> *   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/
>

*
*   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/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index