Announcement

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

  • On capture program drop

    Have you ever seen the line
    Code:
    capture program drop pgmname
    inside an ado-file? Have you written it yourself? Chances are you have. It is utterly unnecessary. Interested? Then this post is for you.

    For those who are worried: capture program drop does no harm in ado-files. You can leave your ado-files unchanged. capture program drop in ado-files does no good either and here is why.


    capture program drop in do-files

    First, I will show when and where capture program drop is useful. Say, we want to implement a program, foo. We might start with a do-file, typing:
    Code:
    program define foo
        display "foo"
    end
    We can execute the do-file to define the program. Then, we can call our program
    Code:
    . foo
    foo
    That worked. What if we were not satisfied with our program and wanted to change it? Say, we changed the do-file to read
    Code:
    program define foo
        display "bar"
    end
    When we try to execute the do-file to define the revised program, Stata tells us
    Code:
    . program foo
    program foo already defined
    r(110);
    Stata complains because there already is a program called foo in memory. We must first drop foo from memory before we define the revised version. The help file for program tells us that the program drop command will drop programs from memory. Thus, we can modify our do-file to read
    Code:
    program drop foo
    program define foo
        display "bar"
    end
    With this change, we can execute our do-file repeatedly and Stata will not complain. Satisfied, we call it a day and close Stata. Next time we open Stata and try executing our do-file to define foo, we find Stata complaining again
    Code:
    . program drop foo
    program foo not found
    r(111);
    This time, Stata complains because there is no program called foo in memory, yet. The "solution" to this problem is
    Code:
    capture program drop foo
    program define foo
        display "bar"
    end
    This is the only situation where capture program drop is useful; inside a do-file that defines the respective program.


    capture program drop in ado-files

    Why do Stata programmers include the line capture program drop in ado-files? I can only speculate on that. Perhaps, they merely forget to delete the line after their do-file morphs into an ado-file. Perhaps, they believe that the line somehow ensures that it is their (current version of the) program that Stata executes when they type
    Code:
    foo
    or whatever their program's name. It does not. What capture program drop really does inside ado-files is result in error every single time it is executed. To see why, we must understand when the line is executed. It is executed when the ado-file is executed. I will now show you when the ado-file is executed. When we type
    Code:
    foo
    Stata first checks whether foo is a built-in command or an abbreviation thereof. If it is, Stata executes this built-in command. Here is a simple illustration using summarize as an example
    Code:
    sysuse auto // just make it easier to follow along
    capture program drop su
    program su
        display "this will never show"
    end
    su
    which results in
    Code:
    . sysuse auto // just make it easier to follow along
    (1978 automobile data)
    
    . capture program drop su
    
    . program su
      1.     display "this will never show"
      2. end
    
    . su
    
        Variable |        Obs        Mean    Std. dev.       Min        Max
    -------------+---------------------------------------------------------
            make |          0
    (output omitted)
         foreign |         74    .2972973    .4601885          0          1
    because su is an abbreviation for summarize and summarize is a built-in command. We can define a program su or even summarize. We could have stored it in an ado-file. We could have even put the line capture program drop su in the ado-file, as I did in the do-file (or command line). Stata would and will still not execute our command. Stata will not even bother looking for an ado-file let alone executes it. To spell it out again: if the command defined in an ado-file has the same name as a built-in command, the line capture program drop inside that ado-files is never executed because the ado-file is never executed. That covers built-in commands.

    What about ado-files then? Let's try:
    Code:
    program regress
        display "not the regress you expected, right?
    end
    regress
    The code above yields
    Code:
    . program regress
      1.     display "not the regress you expected, right?
      2. end
    
    . regress
    not the regress you expected, right?
    What happened here? When we type
    Code:
    regress
    Stata checks whether regress is a built-in command. It is not. Stata then looks for a program regress defined in memory. If it finds one, Stata executes it. That's right. Stata still does not bother looking for an ado-file. In the example code above, Stata finds our regress in memory and executes it. Don't believe me? Type
    Code:
    . regress
    not the regress you expected, right?
    Stata executes our regress again. It does not execute Stata's regress defined in regress.ado because it does not even look for regress.ado let alone execute it. And that would not change even if regress.ado had the line capture program drop regress, which it rightfully does not have.

    When then is the line capture program drop inside ado-files executed? Well, when the ado-file itself is executed. And that happens if and only if the command that the ado-file defines is neither a built-in command nor a program defined in memory. But if there is no such program defined in memory, there is obviously no need to drop it. In fact, any attempt to drop a program that is not defined from memory will result in error. This is why the line capture program drop in ado-files will always result in error and is, thus, utterly unnecessary.

    I could go on and write about dropping sub-programs from ado-files but it turns out that the takeaway message is the same: capture program drop is useful in do-files and useless in ado-files.
    Last edited by daniel klein; 13 Jul 2024, 15:01.
Working...
X