EXIT FAR

EXIT FAR is een manier om snel een stuk code in een lopende procedure te bereiken waar een bepaalde gebeurtenis, bij 
voorbeeld een fout, wordt afgehandeld, die in een onder de lopende procedure hangende procedure is opgetreden. De lopende 
procedure kan ook het hoofdprogramma zijn.

Stel in procedure MainProc wordt aan de gebruiker een sleutel gevraagd met behulp waarvan hij een bepaalde toegangscode 
kan verkrijgen. De bepaling van de toegangscode is heel ingewikkeld en op voorhand kan niet worden bepaald of een bepaalde 
sleutel geldig is. MainProc roept een procedure aan om vast te stellen of de sleutel geldig is en zo ja, wat de bijbehorende 
toegangscode is. Die procedure roept weer een andere procedure aan, en die op zijn beurt roept weer andere procedures aan, 
enzovoort. Er hangt dus een heel wortelstelsel van procedures aan. Stel nu dat in een van die procedures, heel diep onderin het 
stelsel wordt vastgesteld dat de sleutel niet geldig is. Zonder EXIT FAR zou je nu een foutcode moeten genereren en dan via 
het hele wortelstelsel van procedures naar boven moeten klimmen om uiteindelijk weer in MainProc aan te komen waar iets 
met die foutcode gedaan kan worden, bij voorbeeld de gebruiker het nog eens laten proberen. Met EXIT FAR is het veel 
gemakkelijker. MainProc kan er als volgt uit zien:

SUB MainProc
' IsGeldig geeft aan of sleutel geldig is. Zo gauw een geldige toegangscode wordt 
gevonden krijgt
' IsGeldig de waarde -1.
DIM IsGeldig AS SHARED INTEGER

' Geef aan naar welk label EXIT FAR moet springen
EXIT FAR AT Destination

DO
  ' Initialiseer geldigheidsindicator (0 = niet geldig)
  IsGeldig = 0
  ' Vraag de gebruiker de sleutel'
  INPUT "Geef sleutel (geheel getal < 65536): "; Sleutel??
  ' Probeer de toegangscode te bepalen
  CALL GetCode(Sleutel??, Code??)
  ' Hier gaan we verder na een EXIT FAR
Destination:
  IF IsGeldig THEN
    PRINT "Uw toeganscode is "; Code??
    EXIT DO
  ELSE
    PRINT "De door u gegeven sleutel is niet geldig."
    PRINT "Wilt u stoppen (<Esc>) of het nog eens proberen (andere
toets)? ";
    DO
      Toets$ = INKEY$
    LOOP WHILE Len(Toets$) = 0
    IF ASC(Toets$) = 27 THEN EXIT DO
  END IF
LOOP
END SUB

De procedure waar de fout is geconstateerd ziet er bij voorbeeld als volgt uit:

SUB Proc316 (....)
' Geldigheidsindicator
DIM IsGeldig AS SHARED INTEGER
...

' Er kan geen geldige toegangscode worden gevonden als i < 0.
IF i < 0 THEN EXIT FAR
...
END SUB

Je kunt dit ook oplossen met ON [LOCAL] ERROR GOTO ..., maar je hebt dan altijd een RESUME nodig.

Bijvoorbeeld:

ON LOCAL ERROR GOTO Ongeldig
DO
...
Destination:
...
LOOP
EXIT SUB
Ongeldig:
RESUME Destination

Handiger is dan:

ON LOCAL ERROR RESUME NEXT

Dat doet hetzelfde als onze EXIT FAR constructie, n.l. na een fout verdergaan met het eerste statement na CALL GetCode. 
In plaats van EXIT FAR genereer je dan een fout met het statement ERROR, bij voorbeeld:

IF i < 0 THEN ERROR 99

Je moet op Destination dan natuurlijk wel testen of ERR de waarde 99 heeft, omdat ook een runtime error kan zijn 
opgetreden.

Probleem met ON ERROR is dat het nogal wat extra code genereert juist omdat het ook probeert om runtime errors af te 
vangen. Als afvangen van runtime errors niet nodig of gewenst is verdient EXIT FAR verre de voorkeur.
Hans Lunsing

