[DELPHI] Sluit n Function in een nested procedure

Pagina: 1
Acties:
  • 183 views sinds 30-01-2008
  • Reageer

  • MisterE
  • Registratie: April 2002
  • Laatst online: 28-08 19:15
ik heb een FUNCTION waarin een PROCEDURE.
Ik moet deze nested procedure meerdere malen gebruiken in die functie, hij zet onder andere de 'functie resultaat'(result) van de functie.

nou de vraag:
Als die nester procedure aangeroepen word moet de hele functie afgebroken worden, wanneer ik gewoon 'Exit' doe gaat ie gewoon verder....
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function IsLineCompatible : Boolean;
var
  bNameCorrect : Boolean;


      Procedure RequiredFieldsAreMissing;
      begin
        cIgnored := cIgnored + 1;
        RESULT := False;
        Exit;
        // now it must close the function...
      end;


begin
  (* Critical/Required Fields *)

  if iName < StringList.Count then
  begin
    if StringList.Strings[iName] <> '' then
    begin
    bNameCorrect := True;
    end
    else RequiredFieldsAreMissing;
  end
  else
    RequiredFieldsAreMissing;
  ;

  //When RequiredFieldsAreMissing is closed the function continues here
  //i don't want that to happen

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:50

mulder

ik spuug op het trottoir

Misschien een while statement, maar eeeh... you tallek ferrie onduidelijk

oogjes open, snaveltjes dicht


Verwijderd

Wat jij wilt kan niet. Je zal gewoon die nested procedure een return waarde mee moeten geven en aan de hand van die waarde kan je dan de andere procedure (de hoofd procedure) afsluiten.

Verwijderd

Het is onmogelijk om een functie in geneste procedure te beeindigen. Dit komt omdat een procedure-aanroep binnen een functie altijd terugkomt na de regel waar je hem hebt aangeroepen vanuit die functie.

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:50

mulder

ik spuug op het trottoir

Will je niet gewoon zoiets doen?
code:
1
2
3
4
5
6
7
function IsLineCompatible(iName): boolean;
begin
  if StringList.Strings[iName]='' then
    Inc(cIgnored);
  else
    result := false;
end;

oogjes open, snaveltjes dicht


  • MisterE
  • Registratie: April 2002
  • Laatst online: 28-08 19:15
...maar ik vond dit wel een mooie oplossing :(

aangezien ik in de functie 'IsLineCompatible' veel factoren heb die ervoor kunnen zorgen dat het 'feestje' niet doorgaat.

hmmm, dan moet ik toch maar een andere 'structuur' bedenken.
Dan word het waarschijnlijk toch een 'externe' functie.
Erg jammer

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 09:50

mulder

ik spuug op het trottoir

Je kunt van die procedure dan beter een function maken die boolean terug geeft. Als je hem dan aanroept van IsLineCompatible:
if RequiredFieldsAreMissing then
Exit;

Maar je hele algo is gewoon vreemd inelkaar gezet eigenlijk

oogjes open, snaveltjes dicht


  • MisterE
  • Registratie: April 2002
  • Laatst online: 28-08 19:15
Op woensdag 17 juli 2002 20:23 schreef Don Facundo het volgende:
Will je niet gewoon zoiets doen?
code:
1
2
3
4
5
6
7
function IsLineCompatible(iName): boolean;
begin
  if StringList.Strings[iName]='' then
    Inc(cIgnored);
  else
    result := false;
end;
iName is de index van een StringList, ik moet eerst controleren of die 'index' uberhaupt bestaat, ivm errors.

Het gaat namelijk om het parsen van een string die met komma's delimeted is: zoals '1,2,3,4'

wel ik moet er zeker van zijn dat
1: er genoeg items zijn
2: dat de juiste waarde erin staat (geen string waar ie denkt integer te staan

Nou, ik weet klinkt allemaal een beetje abstract, maar een andere weg zie ik niet....

Verwijderd

Op woensdag 17 juli 2002 20:00 schreef MisterE het volgende:
Als die nester procedure aangeroepen word moet de hele functie afgebroken worden, wanneer ik gewoon 'Exit' doe gaat ie gewoon verder....
Ook al roep je een externe procedure B aan vanuit procedure A dan zal procedure B er nooit voor kunnen zorgen dat procedure A afgekapt wordt. Hij zal gewoon weer terug keren naar procedure A.

  • MisterE
  • Registratie: April 2002
  • Laatst online: 28-08 19:15
zal ff iets beter uitleggen hoe het werkt:

ik heb een globale TStringList;
ik moet de data parsen, dus ik lees een string en die haal ik 'uit elkaar' met een procedure,de waarden worden in de stringlist gezet.

en nou heb ik deze functie die controleerd de data in de stringlist wel goed is, daarom moet ik eerst checken of er genoeg items zijn, en ook of een conversie wel goed zou gaan.

...ik hoop dat dit iets meer duidelijker maakt

Verwijderd

Abort; ofzo.. vind ik wel een lelijke oplossing.

  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 31-08 21:58

Delphi32

Heading for the gates of Eden

Ik sluit me aan bij DiFool, maar ik zou niet een EAbort raisen. Liever een EConversionFailed of ERequiredFieldsMissing, want je wil vast ergens weten wat er mis is gegaan. Dan is een Abort veel te 'silent' :)
Als je de exception dan raised in je procedure RequiredFieldsAreMissing (hetgeen eigenlijk een function moet zijn maar ach), kapt je IsLineCompatible ermee. Stop de exception trapping mechanisme in de aanroepende functie en voilà.

Verwijderd

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function IsLineCompatible : Boolean;
var
  bNameCorrect : Boolean;

      Procedure RequiredFieldsAreMissing;
      begin
        cIgnored := cIgnored + 1;
        RESULT := False;
        Exit;
        // now it must close the function...
      end;


begin
  Result:=true //<< add this line
  (* Critical/Required Fields *)

  if iName < StringList.Count then
  begin
    if StringList.Strings[iName] <> '' then
    begin
    bNameCorrect := True;
    end
    else RequiredFieldsAreMissing;
  end
  else
    RequiredFieldsAreMissing;
  ;

if not result then exit; //<< add this line
  //When RequiredFieldsAreMissing is closed the function continues here
  //i don't want that to happen

Verwijderd

Op woensdag 17 juli 2002 20:35 schreef MisterE het volgende:
zal ff iets beter uitleggen hoe het werkt:

ik heb een globale TStringList;
ik moet de data parsen, dus ik lees een string en die haal ik 'uit elkaar' met een procedure,de waarden worden in de stringlist gezet.

en nou heb ik deze functie die controleerd de data in de stringlist wel goed is, daarom moet ik eerst checken of er genoeg items zijn, en ook of een conversie wel goed zou gaan.

...ik hoop dat dit iets meer duidelijker maakt
Zoals ik dit lees zou ik het gewoon heel anders doen:
code:
1
2
3
4
5
6
7
8
9
procedure MaakErAllemaalLosseItemsVan(const AStringList: TStringList);
var
  I: Integer;
begin
  AStringList.Text := StringReplace(AStringList.Text, ',', #13#10, [rfReplaceAll]);
  for I:=0 to AStringList.Count-1 do
    if IntToStr(StrToIntDef(AStringList[I], 0))<>AStringList[I] then
    raise EConvertError.Create('Hier hebben we het foutje te pakken!');
end;

Code heb ik niet kunnen testen maar lijkt het idee lijkt me duidelijk.
Pagina: 1