Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   "FinalllyExit" gewünscht (https://www.delphipraxis.net/160164-finalllyexit-gewuenscht.html)

stahli 30. Apr 2011 10:53

Delphi-Version: 5

"FinalllyExit" gewünscht
 
Ich würde mir folgende Delphi-Syntax wünschen:

Delphi-Quellcode:
function MyFunc(var Counter: Integer): Real;
var
  O: TMyObject;
begin
  O := TMyObject.Create;
  O.MachWas(Counter);
  if (O.Dies) then
    Exit(Random)
  else
  if (O.Das) then
    Exit(0);
  Result := 1 / 0; // Exception
FinallyExit: // <-- Vor dem Aussprung IMMER ausführen, was folgt
  FreeAndNil(O);
  Inc(Counter);
end;

Es geht mir hier nur darum, dass vor dem Aussprung aus der Funktion IMMER noch irgend etwas erledigt wird.
FinallyExit könnte also ein automatisches GoTo-Label implemententieren, so dass auch Exit dort hin führt.
Ebenso könnte dieses Konstrukt als Try-Finally-Block fungieren.

Um das zu erzielende Ergebnis umzusetzen, müsste man bisher einen Try-Finally-Block definieren und die Exit-Anweisungen durch GoTo ersetzen, wobei hier zuvor noch Result zugewiesen werden müsste.
Ich habe mir eine solche Syntax schon öfters gewünscht.

Was haltet Ihr davon?

Neutral General 30. Apr 2011 10:57

AW: "FinalllyExit" gewünscht
 
Schonmal ausprobiert?

exit springt innerhalb eines try-finally-Blocks in den finally-Block ;)

jfheins 30. Apr 2011 10:57

AW: "FinalllyExit" gewünscht
 
Überflüssig.

Exakt diese Funktionalität wird bereits durch try-finally abgedeckt. Falls du das nicht glaubst, zeige bitte ein Stück Code wo das finally nicht ausgeführt wird ;)

stahli 30. Apr 2011 11:06

AW: "FinalllyExit" gewünscht
 
Ok danke. Klar glaube ich Euch das, aber ich wusste das nicht.

Ich arbeite selten mit try-Blöcken.
Ich hatte beim programmieren lernen gelesen, dass man try-Blöcke (nur) verwendet, um Fehlermeldungen bei erwarteten (und zu tolerierenden) Fehlern zu unterdrücken.
Also z.B. bei I/O-Funktionen.

Das steckt halt so drin. Aber ich werde mir das noch mal genauer ansehen...

Danke!

himitsu 30. Apr 2011 11:10

AW: "FinalllyExit" gewünscht
 
Try-Except = auf Fehler (Exceptions) reagieren ... fast so, wie du es gelernt hast

Try-Finally = immer einen bestimmten AufräumCode ausführen, egal was passiert



Aber nicht "unterdrücken", sondern behandeln. :warn:

Zacherl 30. Apr 2011 11:11

AW: "FinalllyExit" gewünscht
 
Eine wichtige und immer wiederkehrende Funktion von try Blöcken ist neben dem Behandeln von Exceptions auch beispielsweise das sichere Freigeben von Resourcen:

Delphi-Quellcode:
MyObject := TObject.Create;
try
  MyObject.DoSomething;
finally
  MyObject.Free;
end;

stahli 30. Apr 2011 11:48

AW: "FinalllyExit" gewünscht
 
Na ja, grundsätzlich sind mir die Fehlerbehandlungen schon klar.

Nur, wenn es irgendwo knallt, ist es m.E. zweitrangig, ein erzeugtes Objekt auch wieder frei zu geben.
Jedenfalls nicht, wenn nicht innerhalb der Fehlerbehandlung selbst wieder ein konstistenter Projektzustand hergestellt wird.

Wenn Exit in einem Try-Block in finally springt, ist das schon mal eine Lösung, aber nicht wirklich das, was ich erwartet habe.

Mal ein Beispiel (ungetestet, nur Resultat Eurer Erklärungen):

Delphi-Quellcode:
function MyFunc: Real;
var
  O: TMyObject;
begin
  O := TMyObject.Create;
  try
    O.DoA;
    if O.A then
      Exit(-1); // ist kein Exit sondern springt in finally - DoNotIfExitBefore wird noch bearbeitet, das wäre ohne Try-Block nicht der Fall, da würde die Funktion VERLASSEN
    O.DoB;
    Result := 1 / 0; // Exception -> Sprung nach finally
    O.DoC;
    Result := O.Result;
  finally
    O.Free;
  end;
  DoNotIfExitBefore; // wird trotz EXIT ausgeführt
end;

Nach Eurer Beschreibung reagiert Exit nicht mehr "normal", wenn man es (z.B. nachträglich) in einen Try-Block kapselt.
Zumindest muss man darauf wohl unbedingt achten, da Exit dann nicht wirklich die Funktion verlässt.

Manchmal möchte man ja eine Funktion unter bestimmten Bedingungen gar nicht ausführen. Wenn man dann das Exit in ein Try-Block aufnimmt, nach dessem finally-end noch etwas ausgeführt wird, dann funktioniert das Exit nicht erwartungsgemäß.

Und zur Objektfreigabe: Wenn im obigen Fall O.DoC nicht mehr ausgeführt wird und man den Fehler nachträglich nicht (durch eine Neuberechnung o.ä. korrigiert) bringt einen die Objektfreigabe auch nicht wirklich weiter. Das Projekt arbeitet fehlerhaft bzw. nicht zuverlässig. Der Fehler muss UNBEDINGT bereinigt werden, aber die Freigabe des Objektes finde ich im Fehlerfall mindestens nachranging.
Ob das Objekt nun aufgelöst wird oder nicht - das Programm beinhaltet fehlerhafte Daten. Die Funktion muss angepasst werden und eine "drohende" Division durch Null selbständig behandeln.

Aber ich schaue mir die ganze Try-Geschichte natürlich nochmal an.

Zacherl 30. Apr 2011 11:53

AW: "FinalllyExit" gewünscht
 
Zur not könntest du dich mit einer Hilfsvariable, die du sagen wir nach dem Exit Befehl auf true setzt aus der Afäre ziehen. Dann checkst du nach dem finally, ob die Variable gesetzt ist und führst nur dann eventuelle weitere Funktionen aus. Guter Stil ist das denke ich allerdings nicht ..

himitsu 30. Apr 2011 11:54

AW: "FinalllyExit" gewünscht
 
Zitat:

// wird trotz EXIT ausgeführt
Nur wenn vorher keine Exception auftrat.

Exit springt aus der Prozedur, aber vorher werden noch die Finally-Abschnitte der umgebenden Try-Finally abgearbeitet.


Bei Try-Except wird, wenn in dem Except-Teil keine neue Exceptions ausgelöst oder die alte Exception weitergeeicht wird, der nachfolgende Code ausgeführt, da die Exception ja abgefangen wurde.

Zitat:

Der Fehler muss UNBEDINGT bereinigt werden
Und dafür ist Try-Finally/Except da, daß man auf "Außnahmen" reagieren kann und dieses entsprechend behandelt.
Dieses kann aber auch bedeuten, daß man noch schnell eine ordentliche Fehlermeldung ausgibt und dann das Programm gezielt und ordnungsgemäß beendet.

stahli 30. Apr 2011 11:59

AW: "FinalllyExit" gewünscht
 
Ok, das (finally und DANN exit) hört sich sehr gut an. Ich schaue mir das wie gesagt noch genau an.

Danke!


PS: In meinem Beispiel ist natürlich klar, dass O vor dem Exit freizugeben wäre. Da war ich etwas zu hektisch. Sorry.

jfheins 30. Apr 2011 12:03

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von stahli (Beitrag 1097832)
Nur, wenn es irgendwo knallt, ist es m.E. zweitrangig, ein erzeugtes Objekt auch wieder frei zu geben.

[...]

... bringt einen die Objektfreigabe auch nicht wirklich weiter. Das Projekt arbeitet fehlerhaft bzw. nicht zuverlässig. Der Fehler muss UNBEDINGT bereinigt werden, aber die Freigabe des Objektes finde ich im Fehlerfall mindestens nachranging.
Ob das Objekt nun aufgelöst wird oder nicht - das Programm beinhaltet fehlerhafte Daten.

Naja, so kann man das nicht sagen. Nimm an, es geht um einen Filestream und du möchtest Daten speichern. Ohne Exceptionhandling. Es tritt ein Fehler auf, der an den benutzer weitergegeben wird - z.B. weil in den Daten ein Fehler drin ist. Er korrigiert den Fehler, will wieder speichern und es geht wieder nicht, weil die Datei noch vom letzten Mal geöffnet ist - der Filestream wurde ja nicht freigegeben!

Ein Speicherleck ist zwar nicht schön aber RAM ist meistens genug da. Wenn andere Ressourcen nicht freigegeben werden, kann es schon ärgerlicher werden. Und genau dafür hat man ja try-finally ;)

Aphton 30. Apr 2011 12:07

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von stahli (Beitrag 1097836)
Ok, das (finally und DANN exit) hört sich sehr gut an. Ich schaue mir das wie gesagt noch genau an.

Ähm, dann werden die folgenden Befehle nicht mehr ausgeführt, da der finally Block unbedingt ausgeführt wird und ein Exit dort veranlasst das Verlassen der Funktion. Dh. es kommt nie zu einem:
DoNotIfExitBefore

Stevie 30. Apr 2011 12:12

AW: "FinalllyExit" gewünscht
 
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

omata 30. Apr 2011 12:16

AW: "FinalllyExit" gewünscht
 
@Stevie: Danke, genau diese Worte habe ich mir beim Lesen dieses Themas gewünscht :thumb:

Aphton 30. Apr 2011 12:49

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Stevie (Beitrag 1097847)
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

Ähm, ja, ich hab das auch die meiste Zeit gedacht, aber um den Code kürzer zu halten, ist es wirklich sinnvoll, hier und da mal Exit zu verwenden.
Ein Beispiel:

Delphi-Quellcode:
// mit Exit
begin
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
end;

// ohne Exit
begin
  if FileExists(Filename) then
  begin // extra Zeile
// + Verschachtelung
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end; // extra Zeile

stahli 30. Apr 2011 12:55

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Aphton (Beitrag 1097855)
Zitat:

Zitat von Stevie (Beitrag 1097847)
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

Ähm, ja, ich hab das auch die meiste Zeit gedacht, aber um den Code kürzer zu halten, ist es wirklich sinnvoll, hier und da mal Exit zu verwenden.
Ein Beispiel:

Delphi-Quellcode:
// mit Exit
begin
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
end;

// ohne Exit
begin
  if FileExists(Filename) then
  begin // extra Zeile
// + Verschachtelung
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end; // extra Zeile

Sehe ich auch so. Der Code wird u.U. einfach kürzer und übersichtlicher.
Zumal man mit Exit(Value) in Funktionen auch gleich einen Result-Wert zuweisen kann.

Zacherl 30. Apr 2011 13:00

AW: "FinalllyExit" gewünscht
 
Grade wenn man viele APIs hintereinander aufruft und immer wieder die Rückgabe prüft, dann hat man ohne Exit spätestens nach der 4.-5. Verschachteltung viel Spaß den Code sauber einzurücken :D

Aphton 30. Apr 2011 13:00

AW: "FinalllyExit" gewünscht
 
Ist die überladene Funktion Exit mit Value neu?
Weil hier bei mir gibts die nicht, ich hab nur ein Exit()!

Stevie 30. Apr 2011 13:01

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Aphton (Beitrag 1097855)
Zitat:

Zitat von Stevie (Beitrag 1097847)
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

Ähm, ja, ich hab das auch die meiste Zeit gedacht, aber um den Code kürzer zu halten, ist es wirklich sinnvoll, hier und da mal Exit zu verwenden.
Ein Beispiel:

Delphi-Quellcode:
// mit Exit
begin
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
end;

// ohne Exit
begin
  if FileExists(Filename) then
  begin // extra Zeile
// + Verschachtelung
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end; // extra Zeile

ROFL, hast du mal bei uns gearbeitet? Jedesmal, wenn ich solchen Code in alten Units sehe, ändere ich das sofort. :wall:
Ernsthaft - um 2 Codezeilen zu sparen? Worin leidet denn beim 2. die Lesbarkeit?
Stell dir vor, man baut mal sowas wie Logging ein:

Delphi-Quellcode:
begin
  Logger.EnterMethod('LoadFile');
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
  Logger.LeaveMethod('LoadFile');
end;

begin
  Logger.EnterMethod('LoadFile');
  if FileExists(Filename) then
  begin
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end;
  Logger.LeaveMethod('LoadFile');
end;
Ah, dann kommt bestimmt die Frage, wie man mit trotz Exit noch bestimmten Code ausführen kann... Merkste was?

Zitat:

Zitat von Aphton (Beitrag 1097859)
Ist die überladene Funktion Exit mit Value neu?
Weil hier bei mir gibts die nicht, ich hab nur ein Exit()!

Ja, keine Ahnung, welche Delphi Version, irgendwas zwischen 7 und 2009

Zitat:

Zitat von stahli (Beitrag 1097857)
Sehe ich auch so. Der Code wird u.U. einfach kürzer und übersichtlicher.
Zumal man mit Exit(Value) in Funktionen auch gleich einen Result-Wert zuweisen kann.

Schonmal Fremdcode debuggt, wo irgendwo nen Exit drin ist und man sich wundert, warum bestimmte Sachen nicht mehr ausgeführt werden?

omata 30. Apr 2011 13:02

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Aphton (Beitrag 1097855)
Ein Beispiel:

Ich persönlich halte von so einer "negativen" Programmierung gar nichts. Mir geht es auch nicht um eine Zeile mehr oder weniger. Es ist jetzt auch nicht nötig, hier irgendwelche Beispiele anzuführen, um die jeweils andere Seite zu überzeugen. Exit ist nunmal nicht nötig, das heißt nicht, dass man es nicht verwenden kann. Nur ist es eben nicht nötig. Trotzdem könnt ihr das natürlich gerne verwenden, lasst ihr uns dann auch die Freiheit, es nicht verwenden zu müssen?
Danke.

himitsu 30. Apr 2011 13:03

AW: "FinalllyExit" gewünscht
 
Ja.
Ich glaub seit 2010/2009.

Wie gesagt, ich fordere ja schon lange und nicht umsonst eine Kennzeichnung in der OH, seit wann es was gibt, so wie man es z.B. aus dem MSDN kennt.

omata 30. Apr 2011 13:03

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Zacherl (Beitrag 1097858)
Grade wenn man viele APIs hintereinander aufruft und immer wieder die Rückgabe prüft, dann hat man ohne Exit spätestens nach der 4.-5. Verschachteltung viel Spaß den Code sauber einzurücken :D

Dafür gibt es eine Tastenkombination (Strg + Shift + U/I).

Zacherl 30. Apr 2011 13:04

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von omata (Beitrag 1097863)
Zitat:

Zitat von Zacherl (Beitrag 1097858)
Grade wenn man viele APIs hintereinander aufruft und immer wieder die Rückgabe prüft, dann hat man ohne Exit spätestens nach der 4.-5. Verschachteltung viel Spaß den Code sauber einzurücken :D

Dafür gibt es eine Tastenkombination (Strg + Shift + U/I).

Das ist nicht das Problem, aber wenn man sich an die vorgegebene Zeilenlänge hält, wirds unschön ..

FredlFesl 30. Apr 2011 13:04

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Stevie (Beitrag 1097847)
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

:wall: Blödsinn. Diesen Quatsch lese ich nun schon seit Jahren immer wieder.
Wenn ein EXIT unsauber wäre, dann gilt das auch für Exceptions.
Auch verstehe ich nicht, wieso es in allen modernen Programmiersprachen so ein Konstrukt gibt. Wenn das unsauber oder veraltet wäre, würde man das doch wegkürzen, so wie Goto's.

"Exit" ist so gut wie immer sauberer, als aus einer verschachtelten Schleife mit Hilfvariablen à la "AbortedFlag" herauszutorkeln.

"Vermeidbar" ist es natürlich immer, aber das sind Schleifen auch: Wozu gibt es schließlich (Rechts-)Rekursion :stupid:

Was ist hier wohl übersichtlicher?
Delphi-Quellcode:
For i:=1 to N Do
  For j := 1 to M Do
  Begin
    If Bla[i,j].HasInvalidData() Then Exit;
    Bla[i,j].Process();
    ...
  End;
...
//
...
i := 1;
Aborted := False;
While (i <= N) and not Aborted Do
Begin
  j := 1;
  While (j <= M) and Not Aborted Do
  Begin
    If Bla[i,j].HasInvalidData() Then
      Aborted := True
    Else
    Begin
      Bla[i,j].Process();
      ...
      Inc(J)
    End;
  End;
  Inc(i);
End;
Allerdings würde ich das "FileExists"-Beispiel auch so wie Stevie codieren.

omata 30. Apr 2011 13:08

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von FredlFesl (Beitrag 1097865)
:wall: Blödsinn. Diesen Quatsch lese ich nun schon seit Jahren immer wieder.

Ja, weil sich an der Gültigkeit dieser Aussage auch nichts ändert.

Aphton 30. Apr 2011 13:09

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Stevie (Beitrag 1097860)
Zitat:

Zitat von Aphton (Beitrag 1097855)
Zitat:

Zitat von Stevie (Beitrag 1097847)
Mag nur meine Meinung, aber für jedes Exit sollte es einen Schlag in den Nacken geben.
Klar, an manchen Stellen kann man sich in etwas vertrackten Konstrukten einfach aus der Affaire ziehen, aber sauber gecoded ist es zu 99.99% vermeidbar.

Ähm, ja, ich hab das auch die meiste Zeit gedacht, aber um den Code kürzer zu halten, ist es wirklich sinnvoll, hier und da mal Exit zu verwenden.
Ein Beispiel:

Delphi-Quellcode:
// mit Exit
begin
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
end;

// ohne Exit
begin
  if FileExists(Filename) then
  begin // extra Zeile
// + Verschachtelung
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end; // extra Zeile

ROFL, hast du mal bei uns gearbeitet? Jedesmal, wenn ich solchen Code in alten Units sehe, ändere ich das sofort. :wall:
Ernsthaft - um 2 Codezeilen zu sparen? Worin leidet denn beim 2. die Lesbarkeit?
Stell dir vor, man baut mal sowas wie Logging ein:

Delphi-Quellcode:
begin
  Logger.EnterMethod('LoadFile');
  if not FileExists(Filename) then Exit;
  LoadFile();
  ProcessFile();
  DoSomethingElseWithFile();
  Logger.LeaveMethod('LoadFile');
end;

begin
  Logger.EnterMethod('LoadFile');
  if FileExists(Filename) then
  begin
    LoadFile();
    ProcessFile();
    DoSomethingElseWithFile();  
  end;
  Logger.LeaveMethod('LoadFile');
end;
Ah, dann kommt bestimmt die Frage, wie man mit trotz Exit noch bestimmten Code ausführen kann... Merkste was?

Ja klar ist mir das bewusst. In diesem Fall ginge es nicht.
Deshalb meinte ich "hier und da".

Aber es gibt Fälle, in denen es andersherum viel leserlicher und besser ist, so wie von Zacherl angesprochen.

Zumindest habe ich so das Gefühl.

Und noch etwas:
Zitat:

"Ernsthaft - um 2 Codezeilen zu sparen?"
Wenn man mehrere Bedingungen hat, sagen wir mal 20, und jede voneinander abhäng ist - dh. alle Bedingungen erfüllt werden müssen, um eine Ebene tiefer gehen zu können, eignet sich hier meines Erachtens nach nur Exit!
Sonst hast du 2*20 Extra Zeilen und ganz zu Geschweigen von der ganzen Einrückung!

Edit:
Zitat:

Zitat von FredlFesl
Allerdings würde ich das "FileExists"-Beispiel auch so wie Stevie codieren.

Ach herjee, das war ja nur aus den Ärmeln geschüttelt. Es ging dabei nicht um den Inhalt, sondern ums Prinzip :P

Daniel 30. Apr 2011 13:12

AW: "FinalllyExit" gewünscht
 
Es gibt keinen Anlass, sich im Ton zu vergreifen - erst recht nicht in der Diskussion, ob man ein Sprachkonstrukt nun verwenden solle oder nicht. Wer das dennoch tut, hat sich hier definitiv zum letzten Mal im Ton vergriffen, meine Güte nochmal. Es ist /NUR/ ein Sprachkonstrukt, vergesst das bitte nicht.

Satty67 30. Apr 2011 13:24

AW: "FinalllyExit" gewünscht
 
Normalerweise prüft man die Rahmenbedingungen ja bevor man einen Process startet
Delphi-Quellcode:
begin
  if FileExists(Filename) then
    ProcessFile(Filename)
  else
    ShowMessage('File not exists');
end;

function ProcessFile(Filename);
begin
  bla...
end;
Was ich meine ist, das man ein Exit eigentlich leicht dadurch verhindert, dass man vorm Aufruf einer Function die Rahmenbedingungen prüft. Wenn dann bei Processing ein Fehler auftritt ist eine Exception auch ganz angemessen geantwortet. Einfach ein Exit am Function-Eingang ist ja für den Aufrufer nicht von erfolgreichem Aufruf zu unterscheiden.

Der andere Fall, ein Exit einzusetzten um Aufgabenblöcke zu überspringen, entspricht einem Goto Ende:. Mehr braucht man ja nicht zu schreiben, ausser das sowas auch durch splitten der Aufgaben pro Funktion meist eleganter gelöst wird.

Stevie 30. Apr 2011 13:32

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Aphton (Beitrag 1097868)
Wenn man mehrere Bedingungen hat, sagen wir mal 20, und jede voneinander abhäng ist - dh. alle Bedingungen erfüllt werden müssen, um eine Ebene tiefer gehen zu können, eignet sich hier meines Erachtens nach nur Exit!
Sonst hast du 2*20 Extra Zeilen und ganz zu Geschweigen von der ganzen Einrückung!

Imho hast du in dem Fall ganz andere Probleme ;)

Zitat:

Zitat von Satty67 (Beitrag 1097871)
Wenn dann bei Processing ein Fehler auftritt ist eine Exception auch ganz angemessen geantwortet. Einfach ein Exit am Function-Eingang ist ja für den Aufrufer nicht von erfolreichem Aufruf zu unterscheiden.

Was ich meine ist, das man ein Exit eigentlich leicht dadurch verhindert, dass man vorm Aufruf einer Function die Rahmenbedingungen prüft.

Der andere Fall, ein Exit einzusetzten um Aufgabenblöcke zu überspringen, entspricht einem Goto Ende:. Mehr braucht man ja nicht zu schreiben, ausser das sowas auch durch splitten der Aufgabe/Funktion meist eleganter gelöst wird.

Danke.

An alle, die jetzt Codeschnippsel produzieren, um von der Nützlichkeit und Unabdingbarkeit von Exit zu überzeugen: Hier habt ihr nen Keks. :lol:

Aphton 30. Apr 2011 13:35

AW: "FinalllyExit" gewünscht
 
Ok, wie es nun aussieht, fällt das in die Kategorie "Geschmackssache".
Denn beides hat ihre Vorteile und Nachteile!
Es gibt Fälle, in denen das eine praktischer ist, das andere weniger.
Fundamentalisten werden das nun verweigern, aber so ist das nunmal!
*Keks_mampf

Edit:
Zitat:

Imho hast du in dem Fall ganz andere Probleme
Jupp, da hast du recht! Aber wenn man mal Quick & Dirty auf saubere Art und Weise programmieren will, ist das geeignet

FredlFesl 30. Apr 2011 13:49

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von omata (Beitrag 1097867)
Zitat:

Zitat von FredlFesl (Beitrag 1097865)
:wall: Blödsinn. Diesen Quatsch lese ich nun schon seit Jahren immer wieder.

Ja, weil sich an der Gültigkeit dieser Aussage auch nichts ändert.

Eben. Es war, ist und bleibt Blödsinn.
Dieser Schwachfug ist in Zeiten aufgekommen, als auffiel, das ein GOTO etwas furchtbar Böses ist und ein EXIT (und BREAK) ja eigentlich auch irgendwie ein GOTO bzw. ein Sprung. Und vor lauter Verteufeln hatte man doch glatt vergessen, das das soooo elegante Exceptionhandling nichts Anderes ist, als ein objektorientiertes SetJmp/LongJmp und damit eigentlich auch zu verteufeln wäre.

Aber gut: Vertreter der Gattung "EXIT's sind schlechter Codestil" behaupten das ja grundsätzlich und sind daher nicht in der Lage, dies grundsätzlich zu belegen.
Zitat:

Zitat von Stevie (Beitrag 1097872)
An alle, die jetzt Codeschnippsel produzieren, um von der Nützlichkeit und Unabdingbarkeit von Exit zu überzeugen: Hier habt ihr nen Keks. :lol:

Dann stell nicht solche absurden Behauptungen auf.

omata 30. Apr 2011 13:50

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von FredlFesl (Beitrag 1097877)
Zitat:

Zitat von omata (Beitrag 1097867)
Zitat:

Zitat von FredlFesl (Beitrag 1097865)
:wall: Blödsinn. Diesen Quatsch lese ich nun schon seit Jahren immer wieder.

Ja, weil sich an der Gültigkeit dieser Aussage auch nichts ändert.

Eben. Es war, ist und bleibt Blödsinn.

Du hast mich falsch verstanden, macht aber nichts.

Satty67 30. Apr 2011 13:59

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Aphton (Beitrag 1097873)
Ok, wie es nun aussieht, fällt das in die Kategorie "Geschmackssache".

Fand das eigentlich eine ganz gute Aussage, um der Sache die Schärfe zu nehmen.

Man kann Exit, Goto, With etc. so einsetzen, dass es übersichtlicher wird. Aber man kann mit den genannten Anweisungen auch Chaos in den Code bringen. Deshalb wird wohl davon abgeraten, zumal es fast immer eine Alternative gibt.

Ich kenne wenig Delphi-Code, wo Exit ungünstig eingesetzt wird und ich deshalb rätseln musste wie eine Funktion arbeitet. Als ich mit C# angefangen hatte, hat mich das inflationär eingesetzte return oft viel Zeit gekostet. Bei Delphi bn ich doch immer wieder froh, dass man von Haus aus etwas strengere Regeln anlegt (auch wenn es manchmal etwas übertrieben sein mag)

Stevie 30. Apr 2011 14:09

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von FredlFesl (Beitrag 1097877)
Zitat:

Zitat von omata (Beitrag 1097867)
Zitat:

Zitat von FredlFesl (Beitrag 1097865)
:wall: Blödsinn. Diesen Quatsch lese ich nun schon seit Jahren immer wieder.

Ja, weil sich an der Gültigkeit dieser Aussage auch nichts ändert.

Eben. Es war, ist und bleibt Blödsinn.
Dieser Schwachfug ist in Zeiten aufgekommen, als auffiel, das ein GOTO etwas furchtbar Böses ist und ein EXIT (und BREAK) ja eigentlich auch irgendwie ein GOTO bzw. ein Sprung. Und vor lauter Verteufeln hatte man doch glatt vergessen, das das soooo elegante Exceptionhandling nichts Anderes ist, als ein objektorientiertes SetJmp/LongJmp und damit eigentlich auch zu verteufeln wäre.

Aber gut: Vertreter der Gattung "EXIT's sind schlechter Codestil" behaupten das ja grundsätzlich und sind daher nicht in der Lage, dies grundsätzlich zu belegen.
Zitat:

Zitat von Stevie (Beitrag 1097872)
An alle, die jetzt Codeschnippsel produzieren, um von der Nützlichkeit und Unabdingbarkeit von Exit zu überzeugen: Hier habt ihr nen Keks. :lol:

Dann stell nicht solche absurden Behauptungen auf.

Als erstes solltest du dich wieder etwas beruhigen. Ich geb dir auch ne Tasse Tee oder Kaffee zum Keks aus 8-)

Meine Meinung zu dem Thema ist folgende (die darf ich ja noch haben und auch kund tun, oder? vielen Dank):
Da in Delphi das Statement
Delphi-Quellcode:
Result := xyz;
nunmal nicht so wie in anderen Sprachen
Delphi-Quellcode:
return xyz
das direkte Verlassen der Routine zur Folge hat und danach weitergarbeitet wird/werden kann, hat man mit dem Benutzen von Exit 2 verschiedene Verhaltensweisen: die "herkömmliche" (Abarbeiten der Routine bis zum Ende) und das direkte Verlassen (mit oder ohne Rückgabewert). Benutze ich die herkömmliche Weise, kann ich sicher sein, dass sich alles immernoch genauso verhält, wenn ich weiteren Code hinzufüge (z.B. Objekt freigeben, Logging Eintrag, etc). Das ist bei einem Exit nicht so. Es verändert den gewohnten Ablauf (im Sinne von 1 Eingang und 1 Ausgang), indem es einen weiteren Ausgang aus der Routine schafft.

Ja, richtig, hier prallen wieder mal die unterschiedlichen Ansichtsweisen, was sauberer Code ist und was nicht, aufeinander. Ich stehe nach wie vor zu meiner Meinung und ich werde auch an irgendeiner Stelle wo es "nötig ist", von den 0.01% der Fälle Gebrauch machen und ein Exit einsetzen. Aber in keinem der hier im Thread erwähnten Fälle.

himitsu 30. Apr 2011 15:19

AW: "FinalllyExit" gewünscht
 
Break und Exit haben nunmal ihre Berechtigung und auch ich nutze sie sehr oft.
Genauso wie das super GOTO wird manchmal verwendet.
(ich wünsche mir auch noch ein GOSUB)

Ja, wenn man ganz pervers ist, dann verwendet man auch noch Exceptions, zur Steuerung des Programmablaufs.
Und Timer, sowie ProcessMessages für langanhaltende Programmteile, anstatt von Threads.


So, jetzt dürft ihr mich steinigen.
ich steh dazu, daß ich Exit und auch manchmal Goto verwende, vorallem wenn sich dadurch der Programmablauf vereinfachen oder übersichtlicher gestalten läßt.

Aphton 30. Apr 2011 16:02

AW: "FinalllyExit" gewünscht
 
Pass auf, dass du nicht gesteinigt wirst. Du läufst hier die Gefahr...
Du hast es ja eh selbst schon befürchtet xD

sx2008 30. Apr 2011 16:28

AW: "FinalllyExit" gewünscht
 
Wenn man Exit richtig einsetzt erhöht das die Lesbarkeit; wenn man es falsch einsetzt verringert man die Lesbarkeit.
Es geht also nicht um die Anzahl der Zeilen oder Optik sondern um die Lesbarkeit.

Nach meiner Erfahrung gilt es dabei zu beachten:

1.) wenn man Exit verwendet, dann möglichst frühzeitig aussteigen
Delphi-Quellcode:
procedure GoodExample1(arg1,arg2,..);
begin
  if arg1 = arg2 then
    Exit;
  // hier folgen einige weitere Anweisungen
  Anweisung1;
  ...
  AnweisungN;
end;
2.) Exit nicht verwenden, wenn man gezwungen wäre Anweisungen zu wiederholen
Delphi-Quellcode:
procedure BadExample2(arg1,arg2,..);
begin
  Machwas;
  if (IrgendeineBedingung) then
  begin
    MachNochIrgendwas; // doppelter Code
    Exit;
  end;
  // hier folgen einige weitere Anweisungen
  .....
  MachNochIrgendwas; // doppelter Code
end;
3.) Exit nur einmal verwenden
Wenn man an mehreren Stellen eine Funktion/Procedure mit Exit verlässt,
dann verschlechtert dies die Lesbarkeit.

4.) Exit aus einer Schleife
Hier zeigt sich ganz klar der Vorteil von Exit; man kann eine Schleife und zugleich
die Funktion/Procedure verlassen, ohne dass der der Schleife folgende Code ausgeführt wird.
Man spart sich so die Verwendung eines boolean Flags.

5.) Exit in "Kleinfunktionen"
Manchmal wird Exit verwendet, ohne wirklich eine Verbesserung der Lesbarkeit zu bringen.
Das zeigt sich z.B. in Funktionen mit nur ganz wenigen Anweisungen
Delphi-Quellcode:
function BadExample2(arg..):Boolean;
begin
  result := False;
  if EineBedingung then
    Exit;  // sehr unschön
  EineEinzigeWeitereAnweisung;
  Result := True;
end;
Dies lässt sich so umschreiben (und man spart sogar eine Zeile):
Delphi-Quellcode:
function GoodExample2(arg..):Boolean;
begin
  result := not EineBedingung; // anstatt "not" besser die Bedingung umformulieren
  if Result then
    EineEinzigeWeitereAnweisung;
end;
Mit diesem Kochbuch kann eigentlich in Bezug auf Exit nichts mehr schiefgehen.
So und nun habt euch wieder lieb!!

Namenloser 30. Apr 2011 16:49

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von sx2008 (Beitrag 1097917)
Wenn man Exit richtig einsetzt erhöht das die Lesbarkeit; wenn man es falsch einsetzt verringert man die Lesbarkeit.
Es geht also nicht um die Anzahl der Zeilen oder Optik sondern um die Lesbarkeit.

Genau so ist es. Ich setze Exit und Break ein, wo es sinnvoll ist. Ich habe sogar letztens zum ersten mal seit 5 Jahren oder so mal wieder ein Goto verwendet, weil – ihr werdet es nicht glauben – es den Code erheblich vereinfacht hat.

Das:
Zitat:

Zitat von FredlFesl
Delphi-Quellcode:
i := 1;
Aborted := False;
While (i <= N) and not Aborted Do
Begin
  j := 1;
  While (j <= M) and Not Aborted Do
  Begin
    If Bla[i,j].HasInvalidData() Then
      Aborted := True
    Else
    Begin
      Bla[i,j].Process();
      ...
      Inc(J)
    End;
  End;
  Inc(i);
End;

ist einfach nicht übersichtlicher als das:
Zitat:

Zitat von FredlFesl
Delphi-Quellcode:
For i:=1 to N Do
  For j := 1 to M Do
  Begin
    If Bla[i,j].HasInvalidData() Then Exit;
    Bla[i,j].Process();
    ...
  End;

Egal wie oft man es behauptet. Ich habe so ähnliche Dinger wie das obere Beispiel (Danke, FredlFesl) tatsächlich schon ein paar mal gesehen und jedes mal Krämpfe bekommen.

Sicher gibt es auch genau so gute Beispiele wie man seinen Code mit Exits und Breaks verhunzen kann.

Es kommt eben immer auf das richtige Maß an. Alles mit Scheuklappen auf eine vorgebene Weise zu machen ist übrigens auch ein Anti-Pattern:
Zitat:

Golden hammer: Assuming that a favorite solution is universally applicable

Stevie 30. Apr 2011 16:58

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von NamenLozer (Beitrag 1097921)
Egal wie oft man es behauptet. Ich habe so ähnliche Dinger wie das obere Beispiel (Danke, FredlFesl) tatsächlich schon ein paar mal gesehen und jedes mal Krämpfe bekommen.

Vielleicht sollte man sich bei dem Beispiel aber auch Gedanken darüber machen, ob man überhaupt HasInvalidData überprüft und nicht einfach eine Exception im Process wirft, wenn dies der Fall ist und das in einem Block außen um die beiden Schleifen behandelt und dementsprechend einen Rückgabewert setzt. Is nämlich sonst für den Aufrufer dieser Routine ziemlich bescheiden, wenn er nicht weiß, ob nun alles Processed ist oder obs irgendwo ausgestiegen ist, weil HasInvalidData true war.

Dazu sag ich dann nur:
Zitat:

Zitat von Aphton (Beitrag 1097873)
wenn man mal Quick & Dirty auf saubere Art und Weise programmieren will, ist das geeignet


Namenloser 30. Apr 2011 17:05

AW: "FinalllyExit" gewünscht
 
Zitat:

Zitat von Stevie (Beitrag 1097924)
Zitat:

Zitat von NamenLozer (Beitrag 1097921)
Egal wie oft man es behauptet. Ich habe so ähnliche Dinger wie das obere Beispiel (Danke, FredlFesl) tatsächlich schon ein paar mal gesehen und jedes mal Krämpfe bekommen.

Vielleicht sollte man sich bei dem Beispiel aber auch Gedanken darüber machen, ob man überhaupt HasInvalidData überprüft und nicht einfach eine Exception im Process wirft

Ja, da magst du recht haben, hab mir das Beispiel nicht soo genau angeschaut, aber es gibt schon recht häufig Fälle, wo man verschachtelte Schleifen hat und aus mehreren raus muss, auch wenn kein Fehler auftritt. Z.B. wenn man in einem Baum einen Knoten sucht o.ä..


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:57 Uhr.
Seite 1 von 2  1 2      

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