Announcement

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

  • Passing a local containing multiple sets of words as a function argument

    Hi all,

    I am using STATA version 15.1
    I'm writing a function that has two arguments: a local and an integer

    Code:
    capture program drop mytest
    program define mytest
        args v_list max_loc
            di "`v_list'"
            di "`max_loc'"
            tokenize `v_list'
            di "`1'"
    end
    
    local vlist = `""one two three" "four five six""'
    mytest v_list = `vlist' max_loc = 7
    I expect to see, in order, something like:

    Code:
    one two threefour five six
    7
    one two three
    But instead, I see:

    Code:
    v_list
    
    v_list
    I'm still trying to wrap my head around local behavior.

    Thanks in advance.

  • #2
    There are two problems with your code.

    The first is that
    Code:
    mytest v_list = `vlist' max_loc = 7
    is not how you call a program in Stata.

    The other is that throughout your program you have used ordinary double-quotes (") to enclose expressions that themselves may contain double-quotes. You need to use Stata's compound double quotes for these. See -help quotes- for more information.

    Code:
    . capture program drop mytest
    
    . program define mytest
      1.     args v_list max_loc
      2.         di `"`v_list'"'
      3.         di `"`max_loc'"'
      4.         tokenize `"`v_list'"'
      5.         di `"`1'"'
      6. end
    
    .
    . local vlist = `""one two three" "four five six""'
    
    . // mytest v_list = `vlist' max_loc = 7
    . mytest `"`vlist'"' 7
    "one two three" "four five six"
    7
    one two three
    
    .
    end of do-file

    Comment


    • #3
      deleted.
      Last edited by Bjarte Aagnes; 07 Jun 2023, 13:15.

      Comment


      • #4
        Thanks Clyde!

        Comment


        • #5
          At the risk of being pedantic, I have a few other things to note here:

          First, you say you pass in the number 7 as an integer. This is not the case strictly speaking. The integer type in Stata's ado language is always a vector (usually not a single number), and it is stored in the global dataset. You might mean something like the scalar type, which represents a singular number, but in this case the symbol 7 is being passed into the program as a local regardless. If you need the `' quotes to reference the content of something, you're probably working with a local. In general, you should think of a local as a dynamically injectable and interpretable piece of syntax. Consider the following simple example:

          Code:
          local foo = "bar"
          gen `foo' = .
          This creates a new variable called bar. Here, the interpreter has found a string in local foo and injected the content of the string into the code before execution. In computer programming, the word "macro" usually refers to code that dynamically writes other code (or even itself). The above is equivalent to this:

          Code:
          local foo = "gen bar = ."
          `foo'
          This is really cool, and very powerful behavior! We can literally write and store an entire line of code, and dynamically inject it into other code later at execution time! This all gets a bit more complicated and unintuitive when you consider the quote system: basically, the quote system boils down to the fact that the interpreter needs to know whether to execute the code in the local in the current line, or later. We have to surround local foo above in quotes, because otherwise Stata doesn't know that it should wait until later to execute everything to the right of the assignment operator (the equals sign). Sometimes you want to execute right away to store the evaluation of an expression (rather than the expression itself) in a local. Stata needs a way to tell the difference, and it does this with the quote system. Likewise, Stata has to strip off the quotes in the second line so that the content of the local `foo' is executed. The quote system can get complicated, and it is a good idea to read the related documentation as Clyde suggests.

          Finally, a few notes about this line:

          Code:
          mytest v_list = `vlist' max_loc = 7
          I'll admit, I'm not exactly sure what you're trying to do here, but it seems like you're trying to treat the -mytest- command like a function, which takes as parameters a vlist local and a max_loc local equal to 7, then returns another local called v_list. There are a few important things to keep in mind. First, this is a fairly strict imperative language. You don't write functions, you write commands, which are different than functions in several key regards. Commands are complex sets of instructions to the Stata software, usually involving complex operations on the globalized data set. Commands don't return anything strictly speaking, but in practice if you need to pass out locals, matrixes, or other information, you can write them to the global environment and access them with (e.g.) the r() function. There are commands (like generate) that use the assignment operator like you have above, but even if you could reproduce this syntax (I'm not sure you can) its not necessary or desirable to do so.

          It also seems like you might want to have a default value for max_loc, which you can then override with the max_loc = 7 syntax. This syntax isn't correct, but you can achieve this behavior with the options syntax. Check out the syntax documentation for the details.
          Last edited by Daniel Schaefer; 07 Jun 2023, 14:12.

          Comment

          Working...
          X