Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Schleifenabbruch durch exception verhindern (https://www.delphipraxis.net/183608-schleifenabbruch-durch-exception-verhindern.html)

bernhard_LA 22. Jan 2015 12:53

Schleifenabbruch durch exception verhindern
 
mein code geht ungefährt wie folgt

Delphi-Quellcode:
     for i := 0 to MaxLoop do
       begin

         try
          aClass := TClass.Create(...)
          aClass.DoA;
          AClass.Do...;


          if AClass.result >0  then
               begin

                 ///  Ergebnisse auswerten
                 ....
                 ....
               end;

         finally
         AClass.Free;
         end;

       end;

AClass umfasst einige 1000 Zeilen Code .
Aktuell wirft AClass mit bestimmten Daten gefüttert eine Exception, vermutlich greife ich in der komplexen Klasse A auf ein internes Feld mit einem falschen Index zu.
Technisch bekomme ich dieses Problem nicht schnell gelöst. Könnte ich als kurzfristige Lösung alle Exceptions ignorieren und die Schleife trotzdem durchlaufen und komplett abarbeiten.

baumina 22. Jan 2015 13:21

AW: Schleifenabbruch durch exception verhindern
 
Eine einzige try-finally um 1000 Zeilen Code ist natürlich ein echtes Problem, da wirst wohl keine "einfache kurzfristige" Lösung finden. Die Schleife wird ja auf jeden Fall komplett durchlaufen, nur der riesige try-finally-Block halt nicht.

Uwe Raabe 22. Jan 2015 13:25

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von baumina (Beitrag 1287446)
Die Schleife wird ja auf jeden Fall komplett durchlaufen, nur der riesige try-finally-Block halt nicht.

Nee! Die Schleife bricht nach dem finally ab und die Exception wird an die nächste Ebene weitergereicht.

So könnte man es lösen:

Delphi-Quellcode:
  for i := 0 to MaxLoop do begin
    aClass := TClass.Create();
    try
      try
        aClass.DoA;
        AClass.Do;

        if aClass.result > 0 then begin
          /// Ergebnisse auswerten
        end;
      except
        { Bug noch diesen Monat fixen! }
        if Now > EncodeDate(2015, 1, 31) then
          raise;
      end;
    finally
      aClass.Free;
    end;
  end;

baumina 22. Jan 2015 13:42

AW: Schleifenabbruch durch exception verhindern
 
Hopsa, mit try-except verwechselt ... peinlich.

Mavarik 22. Jan 2015 16:21

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von baumina (Beitrag 1287448)
Hopsa, mit try-except verwechselt ... peinlich.

was fehlt ist ein

Delphi-Quellcode:
try

FinallyAndExcept
end;
Mavarik

Der schöne Günther 22. Jan 2015 16:26

AW: Schleifenabbruch durch exception verhindern
 
wat :roteyes:

Uwe Raabe 22. Jan 2015 16:33

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von Mavarik (Beitrag 1287471)
was fehlt ist ein

Delphi-Quellcode:
try

FinallyAndExcept
end;

Das ist aber wieder etwas anderes, denn das finally wird immer ausgeführt, während das except nur im Fehlerfall ausgeführt wird. Aber sowas hier wär manchmal schön:

Delphi-Quellcode:
try
  ...
except
  ...
finally
  ...
end;
Wobei ich mir da sogar vorstellen kann, daß man über die Anordnung try - except - finally oder try - finally - except auch festlegen kann, ob der except- oder der finally-Code erst ausgeführt werden soll. Aber ehrlich gesagt tun es ja auch die beiden geschachtelten try-Blöcke.

Mavarik 22. Jan 2015 16:34

AW: Schleifenabbruch durch exception verhindern
 
wie oft hat man

Delphi-Quellcode:
try
 try
 except
 end;
finally
end;
besser ein

Delphi-Quellcode:
try
...
FinallyAndExcept
end;
Dat is nen Featurerequst @EMBT

Der schöne Günther 22. Jan 2015 16:59

AW: Schleifenabbruch durch exception verhindern
 
In Java gibt es bspw.
Code:
try {
   // Stuff
}
catch(IOException e) {
   System.out.println("Exception: ");
   e.printStackTrace();
}
finally {
   // Stuff
}

Das zwingend in try..except und try..finally aufzusplitten ist eins der wenigen Dinge die ich in Pascal irgendwie schöner als anderswo finde. :thumb:

Liegt wahrscheinlich an der Einrückung, man sieht so deutlicher was auf jeden Fall abläuft und was nur im Fehlerfall. In Javas try..catch..finally sieht das alles gleichberechtigt aus.

mm1256 22. Jan 2015 17:00

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von Mavarik (Beitrag 1287474)
Dat is nen Featurerequst @EMBT

+ 1 :thumb:

himitsu 22. Jan 2015 17:06

AW: Schleifenabbruch durch exception verhindern
 
Finally wird immer verarbeitet und wenn man zwischen Finally und End eine aktuell eventuell vorhandene Exception verwirft, dann hätte man auch jetzt schon sein Try-Finally&Except. :roll:
Wenn man nur prüfen will, ob eine Exception auftrat, um diese eventuell zu loggen, aber nicht um sie zu behandeln, dann reicht ebenfalls ein Try-Finally und ein 22-buchstabiger Befehl.

Aber ja, um 2-3 Zeilen und eine Ebene in der Einrückung zu sparen, wäre ein Try-Finally-Except-End, bzw. Try-Except-Finally-End bestimmt ganz nett.

BadenPower 22. Jan 2015 17:18

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von himitsu (Beitrag 1287478)
Aber ja, um 2-3 Zeilen und eine Ebene in der Einrückung zu sparen, wäre ein Try-Finally-Except-End, bzw. Try-Except-Finally-End bestimmt ganz nett.

Dann aber auch noch gleich ein echtes ELSEIF, welches ich persönlich sehr vermisse.

Sir Rufo 22. Jan 2015 17:43

AW: Schleifenabbruch durch exception verhindern
 
Das
Delphi-Quellcode:
try ... except ... finally ... end
ist doch nur was für Leute mit Exception-Phobie :mrgreen:

himitsu 22. Jan 2015 18:41

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von BadenPower (Beitrag 1287479)
Dann aber auch noch gleich ein echtes ELSEIF, welches ich persönlich sehr vermisse.

Du mein ein CASE-OF? :lol:

Ja, ein CASE für nicht-ordinale Typen wäre bestimmt auch nett.
Und dann noch nicht-konstante Werte im CASE. :stupid:

Das ist ja nicht so ganz der Renner:
Delphi-Quellcode:
case IndexStr(S, ['aaa', 'bbb', 'ccc']) of
  0{aaa}: ...;
  1{ddd}: ...;
  2{ccc}: ...;
end;

Sir Rufo 22. Jan 2015 18:58

AW: Schleifenabbruch durch exception verhindern
 
Also ein
Delphi-Quellcode:
case
mit variablen oder nicht ordinalen Werten wäre zwar charmant, aber zu welchem Preis?

Einige Fehler finde ich erst zur Laufzeit (z.B. ein Wert ist doppelt vorhanden). Da macht es schon eher Sinn sich einen solchen Case als Klasse mit Closures/Methoden zusammenzubauen. Man benötigt eine Factory-Klasse was daraus ein Closure baut.

Delphi-Quellcode:
var MyCase : TProc<string>;

MyCase := TCaseFactory<string>
  .Case( 'foo', procedure begin ShowMessage( 'Moin' ); end )
  .Case( 'bar', procedure begin Application.MainForm.Close; end )
  .Else( procedure begin end )
  .Build;

MyCase( 'bar' );

BadenPower 22. Jan 2015 19:09

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von himitsu (Beitrag 1287494)
Zitat:

Zitat von BadenPower (Beitrag 1287479)
Dann aber auch noch gleich ein echtes ELSEIF, welches ich persönlich sehr vermisse.

Du mein ein CASE-OF? :lol:

Nein, eigentlich nicht, sondern ein IF-ELSEIF-ELSE.

Delphi-Quellcode:
if (Bedingung1) then
 begin
  ...
 end
elseif (Bedingung2) then
 begin
  ...
 end
elseif (Bedingung3) then
 begin
  ...
 end
else
 begin
  ...
 end;
Als bekennender "Begin-End"- und Einrückungsfetischist sieht das nämlich immer so aus:

Delphi-Quellcode:

if (Bedingung1) then
 begin
  ...
 end
else
 begin
  if (Bedingung2) then
   begin
    ...
   end
  else
   begin
    if (Bedingung3) then
     begin
      ...
     end
    else
     begin
      ...
     end;
   end;
 end;
Und jetzt stell Dir vor Du musst 10-15 Bedingungen prüfen.

Dejan Vu 22. Jan 2015 19:17

AW: Schleifenabbruch durch exception verhindern
 
Lustig, das Niemand was an diesem 1000 Zeilen Monstrum auszusetzen hat.

Mein Tipp wäre: Anstatt den Fehler fürs Erste zu ignorieren, und für 'try...finally...except..end' (oder umgekehrt) zu voten, oder mit anderen Nice-To-Have-Features zu liebäugeln, würde ich mal das Refaktoring-Beil herauskramen.

Deine Klasse ist zu komplex und das hast du nun davon.

Delegiere Teile der Funktionen deiner Klasse in andere (neue) Klassen.
Gruppiere Methoden in deiner Riesenklasse, die gemeinsame private Variablen verwenden und lagere sie aus.
Wenn eine Methode viele andere Methoden aufruft, wäre das auch ein Kandidat für eine eigene Klasse.

Dabei räumst Du auf und vielleicht findest Du den Fehler dann. Wenn nicht, dann prüfe einfach die einzelnen Methoden und schreibe Unittests.

himitsu 22. Jan 2015 19:28

AW: Schleifenabbruch durch exception verhindern
 
Über die 1000 Zeilen hatte man sich bereits auf Seite 1 aufgeregt.

Als bekennender "Keine unnötigen Klammern oder Begin-End und Bedin-End in selber Zeile"-Fetischist kann ich das Problem nicht erkennen. :mrgreen:
Delphi-Quellcode:
if Bedingung1 then
  ...
else if Bedingung2 then
  ...
else if Bedingung3 then
  ...
else
  ...;

if Bedingung1 then begin
  ...
end else begin
  ...
end;

Uwe Raabe 22. Jan 2015 19:28

AW: Schleifenabbruch durch exception verhindern
 
Zitat:

Zitat von Dejan Vu (Beitrag 1287501)
Lustig, das Niemand was an diesem 1000 Zeilen Monstrum auszusetzen hat.

Natürlich wäre das der korrekte Ansatz. Allerdings steht ausdrücklich im ersten Post:

Zitat:

Zitat von bernhard_LA (Beitrag 1287444)
Technisch bekomme ich dieses Problem nicht schnell gelöst.

Ich gehe also davon aus, daß dieser (obwohl bessere) Weg hier aus Zeitgründen nicht eingeschlagen werden kann oder soll.

Dejan Vu 22. Jan 2015 20:59

AW: Schleifenabbruch durch exception verhindern
 
Ich glaube, das man hier vor lauter Wald den Baum nicht sieht. Bugs in so einem Klassenmonstrum kann man i.A. "technisch nicht schnell" lösen.

Da ich aber auch darauf poche, den Eingangspost zu lesen und den TE ernst zu nehmen, muss das akzeptieren. Danke für den Hinweis.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz