Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Where to Specify Temporary Names for Local Macros Inside Ado Files

    Stata Listers:

    I have a general question about where to specify temporary names for local macros inside ado files.

    I use Stata version 15.1 and it is fully updated.

    For temporary variables in Ado files, Baum gives the very helpful advice (in his book I believe) that the tempvar command can be used anywhere in an ado file, and you can list all the temporary variables that are going to be created in one place.

    Does the same rule apply for the temporary names that are applied to local macros inside the Ado file?

    Does the tempname command have to come right after the local it refers to is created?

    In many of my Ado files, I have the "tempname" command on numerous lines, and they make my program harder to navigate. If I could consolidate them, it would shorten my programs significantly and would help me make fewer mistakes.

    I also just want to make sure the local macros inside the Ado file aren't interfering with local macros outside the Ado file if they happen to share the same name.

    An admittedly minor issue is the following. When you put the tempname (or tempvar) command inside a loop, as in the following example, a buildup of local macros that might slow computing in an extreme case occurs.
    foreach examplelocal of local examplelocal2 {
    tempname `examplelocal'
    gen `examplelocal'=5
    }
    Specifying "tempvar" inside a loop resulted in enough temporary variables to cause Stata to stop running, when I didn't know you could specify all the temporary variables at once (and therefore outside the loop).
    The bottom line is I just don't like the local macros building up.

    Generally, what are best practices for where the "tempname" command should be placed in Ado files?

    I've experimented with this and have looked through the documentation, but would still value guidance from experienced Stata users.

    Thanks,

    Carl

  • #2
    Originally posted by Carl Klarner View Post
    I also just want to make sure the local macros inside the Ado file aren't interfering with local macros outside the Ado file if they happen to share the same name.
    That cannot happen because, by definition, local macros are local in scope. There is no need to have temporary names for local macros in the first place.

    Best
    Daniel

    Comment


    • #3
      Hi Daniel,

      I see where my mistake was (see below).

      However, what is still unresolved is what "local in scope" means specifically.

      "Local in scope" clearly means that local macros will be discarded at the end of a block of code that is run. However, what is at issue is whether it also means that local macros will automatically be discarded WITHIN a block of code that is run after an Ado file has been called on and concluded, and there is still more code running (and the Ado file hasn't specified that the local macro in question is a "temporary local macro" with the "tempname" command (see Baum Introduction to Stata Programming 2nd edition, pages 235-236)).

      Where I went wrong is that I didn't see that the "tempname" command is only necessary for specific types of local macros: scalars and matrices. Baum is only talking about scalars and matrices there, and that's also true of page 290 of the pdf documentation (Stata Programming Ref Manual).

      When I've run experiments I found the same.

      For example, if I have an Ado file command named SOMEADOFILECOMMAND that has a local macro called "varlist2" that is equal to "ddd eee fff" and I run

      local varlist2 aaa bbb ccc
      SOMEADOFILECOMMAND
      di "`varlist2'"

      The output is "aaa bbb ccc", as desired.

      Can someone confirm that I'm correct about how I was incorrect in my earlier thinking? I don't want a freak accident to occur.

      Thanks,

      Carl

      Comment


      • #4
        Also, the code

        Originally posted by Carl Klarner View Post
        Code:
        foreach examplelocal of local examplelocal2 {
        tempname `examplelocal'
        gen `examplelocal'=5
        }
        will most likely not do what you think or want. The first time through the loop,

        Code:
        tempname `examplelocal'
        `examplelocal' evaluates to the first element in local macro examplelocal2; let us assume that the first element in examplelocal2 is foo. It is, at this point, irrelevant what foo refers to; it is just a string to Stata. The code above, thus, evaluates to

        Code:
        tempname foo
        What does this mean to Stata? Basically, Stata comes up with a name, say __000042, and stored that name in local macro foo. Basically, the result of

        Code:
        tempname foo
        is the exact same as the result of

        Code:
        local foo __000042
        Using tempname instead of local, you tell Stata to keep track of __000042 and delete the object (variable, scalar, matrix, etc.) with that name when the (a)do-file concludes.

        Anyway, you have asked for a temporary name and Stata stored one in local macro foo. You refer to that name as `foo'. Now look at closely at your code. You type

        Code:
        gen `examplelocal'=5
        This line will create a variable with the permanent(!) name foo. You probably wanted to type

        Code:
        gen ``examplelocal''=5
        which evaluates to

        Code:
        gen `foo'=5
        which in turn evaluates to

        Code:
        gen __000042=5
        creating the temporary variable __000042.

        Best
        Daniel
        Last edited by daniel klein; 02 Mar 2019, 10:50.

        Comment


        • #5
          Carl, sorry I did not see your answer when I wrote the above; I think it is still helpful.

          Here are more clarifications.

          Originally posted by Carl Klarner View Post
          Where I went wrong is that I didn't see that the "tempname" command is only necessary for specific types of local macros: scalars and matrices.
          Not quite correct. Scalars and matrices are not local macros; they are scalars and matrices. These can be temporary objects, meaning that their names are stored in local macros created by tempname. But that does not make the scalar or matrix itself a local macro.


          Originally posted by Carl Klarner View Post
          what "local in scope" means specifically.
          Well, when you work interactively, locals are defined within the session of Stata, meaning until you close Stata and open it again. When you define a local macro in a do-file, then that local is visible within this do-file. When this do-file calls other do-files, or ado-files, these may define their own local macros; none of these will be visible in the first do-file and the first do-file's locals are not visible in the do-files, or ado-files, called.

          The same is not always true in ado-files, because ado-files often define more than one program; local macros defined in one program are visible inside this program. Of course, you can define programs in do-files, too. In that case, the local defined inside a program is visible within that program not within the rest of the do-file.

          Best
          Daniel

          Comment


          • #6
            Hi Daniel,

            Thanks for the replies.

            My apologies for the distracting example.

            Instead of writing the line

            gen `examplelocal'=5

            I should have written

            SOME RANDOM COMMAND

            I just put in a random bit of code for filler. The point I was making was irrelevant to what the command was.

            Thanks,

            Carl

            Comment


            • #7
              Hi Daniel,

              Awesome! In addition to resolving my questions you added extra information that will be useful also (i.e., "The same is not always true in ado-files....")

              I've just deleted all the unnecessary "tempname" commands from my Ado files and they look a lot better.

              Thanks much,

              Carl

              Comment

              Working...
              X