If you add a return code, then the code will stop within the loop:
prog foo3
local num 1 2 3
foreach n of local num {
if "`n'"=="2" {
di "`n' => exit"
exit 119
}
di "`n'"
mac shift
}
di "not to be reached"
end
. discard
. foo3
1
2 => exit
r(119);
prog foo4
local list 1 2 3
foreach l of local list {
di "`l'"
exit 119
}
di "howdy"
end
. foo4
1
r(119);
Scott
> -----Original Message-----
> From: [email protected] [mailto:owner-
> [email protected]] On Behalf Of Ben Jann
> Sent: Monday, October 30, 2006 3:18 PM
> To: [email protected]
> Subject: st: Use of -exit- within -foreach- or -forvalues-
>
> Hi, I always thought that using -exit- within a -program-
> would terminate the program no matter what. However, I
> now used -exit- within a -foreach- loop and -exit- did
> not seem to have any effect. Here is an example:
>
> <cut>
> . prog test1
> 1. local num 1 2 3
> 2. foreach n of local num {
> 3. if "`n'"=="2" {
> 4. di "`n' => exit"
> 5. exit
> 6. }
> 7. di "`n'"
> 8. mac shift
> 9. }
> 10. di "not to be reached"
> 11. end
>
> . test1
> 1
> 2 => exit
> 3
> not to be reached
> <cut>
>
> Neither the -foreach- loop, nor the program is
> terminated. This is not what I expected and I cannot
> find anything about it in the documentation.
> Furthermore, note that -exit- works as expected within
> a -while- loop (this is documented in [P] while):
>
> <cut>
> . prog test2
> 1. local num 1 2 3
> 2. tokenize "`num'"
> 3. while "`1'"!="" {
> 4. if "`1'"=="2" {
> 5. di "`1' => exit"
> 6. exit
> 7. }
> 8. di "`1'"
> 9. mac shift
> 10. }
> 11. di "not to be reached"
> 12. end
>
> . test2
> 1
> 2 => exit
> <cut>
>
> I checked the Statalist Archive and found a similar
> thread, see
>
> http://www.stata.com/statalist/archive/2005-11/msg00809.html
>
> Stephen Jenkins ([email protected]) reported a
> problem with -exit- within a -forvalues- loop and
> Ken Higbee ([email protected]) gave an answer. However,
> Ken's answer does appear incorrect (or at least
> incomplete) to me. Stephen's code looked something
> like
>
> forval i = ... {
> ...
> if mod(...) == 0 {
> ...
> exit
> }
> }
>
> and part of Ken's answer was:
>
> "-exit- without a return code (or in other words,
> with a zero return code) pops you out of the current
> process. The -if mod(...) == 0 { ... }- block is
> considered a process, so the -exit- is only popping
> you up out of that -if- block of code, and since the
> return code is zero, there is no error and the -forval-
> loop continues on its merry way."
>
> However, -exit- does not terminate the loop even if
> not included in an -if- block:
>
> <cut>
> . prog test
> 1. local list 1 2 3
> 2. foreach l of local list {
> 3. di "`l'"
> 4. exit
> 5. }
> 6. di "howdy"
> 7. end
>
> . test
> 1
> 2
> 3
> <cut>
>
> Furthermore note that the -display- command after the
> loop is not executed. So -exit- does not terminate
> the loop but it terminates the program? Huh?
>
> Although it is not much of a problem to me that -exit-
> does not work within -foreach- (I just use -while-
> instead of -foreach-), I'd like make the following
> points:
>
> - It is very irritating that -exit- has a different
> effect in a -while- loop than in a -foreach- or
> -forvalues- loop. One would not expect that and it
> is likely to cause confusion. Documentation should
> say something about it (especially since use of -exit-
> is documented for -while-).
>
> - It is still unclear to me what is going on. Why does
> -exit- not terminate the program if used in a
> -foreach- loop? Can anyone clarify? And what exactly
> is a "process" in [P] exit?
>
> - Ken's advice was to use -continue, break- ("Okay, so
> what should you do? Use the -continue, break- command
> to exit out of the -forval- loop; see '[P] continue'").
> However, the reason for using -exit- is to terminate
> the whole -program- (also in Stephen's case).
>
> ben
>
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/