Have you ever seen the line
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:
We can execute the do-file to define the program. Then, we can call our program
That worked. What if we were not satisfied with our program and wanted to change it? Say, we changed the do-file to read
When we try to execute the do-file to define the revised program, Stata tells us
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
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
This time, Stata complains because there is no program called foo in memory, yet. The "solution" to this problem is
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
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
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
which results in
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:
The code above yields
What happened here? When we type
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
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.
Code:
capture program drop pgmname
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
Code:
. foo foo
Code:
program define foo display "bar" end
Code:
. program foo program foo already defined r(110);
Code:
program drop foo program define foo display "bar" end
Code:
. program drop foo program foo not found r(111);
Code:
capture program drop foo program define foo display "bar" end
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
Code:
foo
Code:
sysuse auto // just make it easier to follow along capture program drop su program su display "this will never show" end su
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
What about ado-files then? Let's try:
Code:
program regress display "not the regress you expected, right? end regress
Code:
. program regress 1. display "not the regress you expected, right? 2. end . regress not the regress you expected, right?
Code:
regress
Code:
. regress not the regress you expected, right?
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.