AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

"FinalllyExit" gewünscht

Ein Thema von stahli · begonnen am 30. Apr 2011 · letzter Beitrag vom 21. Mai 2011
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.549 Beiträge
 
Delphi 12 Athens
 
#1

AW: "FinalllyExit" gewünscht

  Alt 30. Apr 2011, 18:21
Im Prinzip sind das alles die selben Funktionalitäten
> "Abbrechen" aka unterbrechen des linearen Programmablaufs

If/Case > überspringen von Befehlen
Continue > einen Schleifendurchgang abbrechen
Break > ganze Schleife abbrechen
Exit > Funktion verlassen
Raise (Exception) > Thread beenden (es sei denn die Exception wird abgefangen > Try-Except)
Halt > Programm sofort beenden (ist voll unsauber und eher für schwerwiegende Poblembehandlungen geeignet)

(Goto könnte man bei mehreren dieser Punkte dazuschreiben)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.052 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: "FinalllyExit" gewünscht

  Alt 30. Apr 2011, 18:38
Im Prinzip sind das alles die selben Funktionalitäten
> "Abbrechen" aka unterbrechen des linearen Programmablaufs

If/Case > überspringen von Befehlen
Continue > einen Schleifendurchgang abbrechen
Break > ganze Schleife abbrechen
Exit > Funktion verlassen
Raise (Exception) > Thread beenden (es sei denn die Exception wird abgefangen > Try-Except)
Halt > Programm sofort beenden (ist voll unsauber und eher für schwerwiegende Poblembehandlungen geeignet)

(Goto könnte man bei mehreren dieser Punkte dazuschreiben)
Und? Nur weils es gibt, isses auch gut?

Und nur, um es nochmal zu betonen, ich sage nicht, man darf das auf keinen Fall niemalsnich verwenden. Aber bereits das Code Beispiel im TE Post zeigte, dass dort Exit mal total falsch plaziert war. Man sollte die Verwendung auf ein absolutes Minumum reduzieren und nicht dort, wo man einfach nur nen Boolschen Ausdruck negieren könnte, nen Exit reindonnern.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (30. Apr 2011 um 18:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: "FinalllyExit" gewünscht

  Alt 30. Apr 2011, 18:40
Die Existenz derer sagt, so wie du es schon angedeutet hast, nichts über ihr Nutzen (nützlich, gut, böse?) aus.
Es liegt alles am Programmierer.

Eigentlich sind wir hier alle in eine Tangente abgedriftet. Wäre nett, wenn man die Diskussion fortsetzen will, nen neuen Thread zu eröffnen!
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: "FinalllyExit" gewünscht

  Alt 19. Mai 2011, 23:07
(anderer Thread)
- FinallyExit (fände ich trotz allem besser als das try-finally-Gewurschtel )
Ich glaube damit stehst du ziemlich allein. Warum sollte man das exakt selbe Feature doppelt implementieren? Bei den restlichen Punkten stimme ich dir aber weitestgehend zu.
Ich habe mal ein Testprojekt angehängt.
An den try-Blöcken stört mich die schlechte Debugbarkeit. Gerade habe ich einen Fehler gefunden, der in einer aufgerufenen Funktion auftrat. Durch den sch... try-Block war der schlechter lokalisierbar.
Ich mag die Dinger nicht und halte sie für wesentlich überschätzt.
Wenn man sie konsequent nutzen will, müsste man quasi jeden Befehl in einen try-Block kapseln.
Delphi-Quellcode:
A:=TA.Create;
B:=TB.Create;
try
  ...
finally
  A.Free;
  B.Free;
end;
Was aber, wenn schon TA.Create fehl schlägt???
Also müsste man dutzende try-Blöcke ineinander schachteln, um wirklich sicher zu sein?
Ich halte das für Unsinn.

In meinem Testprojekt kann man sehen, dass "end(normal)" nur in einem Fall aufgerufen wird.
Was ist aber bei 2 verschachtelten oder aufeinander folgenden try-Blöcken?

Ich halte ein Standardlabel "FinallyExit" für sehr sinnvoll, das einfach IMMER vor dem Verlassen einer Funktion/Prozedur angesprungen wird, egal was vorher auch immer passiert ist.
Sehr schwierig sollte das nicht lösbar sein, da ja weitestgehend nur die Exit-Sprungadresse geändert werden müsste.

PS: Das mit einem selbst definierten Label zu testen, wäre etwas umständlich, da man Exit(VALUE) so nicht (mit einer Anweisung) simulieren kann.


Delphi-Quellcode:
unit fTestFinallyExit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TFormTestFinallyExit = class(TForm)
    ButtonTest: TButton;
    Memo: TMemo;
    RadioGroupMode: TRadioGroup;
    procedure RadioGroupModeClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    function Test: String;
  end;

var
  FormTestFinallyExit: TFormTestFinallyExit;

implementation

{$R *.dfm}

procedure TFormTestFinallyExit.RadioGroupModeClick(Sender: TObject);
begin
  Memo.Lines.Add('-----' + RadioGroupMode.Items[RadioGroupMode.ItemIndex] + '-----');
  Memo.Lines.Add(Test);
  Memo.Lines.Add('');
end;

function TFormTestFinallyExit.Test: String;
var
  S: String;
  I: Integer;

  procedure Add(SA: String);
  begin
    S := S + SA + #13#10;
  end;

begin
  Result := 'nix';
  S := '';
  I := 0;
  Add('begin');
  if RadioGroupMode.ItemIndex = 1 then
  begin
    Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
    Exit;
  end;
  if RadioGroupMode.ItemIndex = 2 then
  begin
    Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
    Exit('#');
  end;
  if RadioGroupMode.ItemIndex = 3 then
  begin
    Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
    Add(IntToStr(1 div I));
  end;
  try
    Add(' try');
    if RadioGroupMode.ItemIndex = 4 then
    begin
      Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
      Exit;
    end;
    if RadioGroupMode.ItemIndex = 5 then
    begin
      Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
      Exit(' #');
    end;
    if RadioGroupMode.ItemIndex = 6 then
    begin
      Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
      Add(IntToStr(1 div I)); // springt in finally und dann Exit ohne Result-Zuweisung
    end;
    Add(' ok');
  finally
    Add(' finally');
    Add('end(finally)');
    Result := S;
  end;
  Add('end(normal)');
  Result := S;
end;

end.
Angehängte Grafiken
Dateityp: png fe.png (32,3 KB, 28x aufgerufen)
Angehängte Dateien
Dateityp: zip TestFinallyExit.zip (568,5 KB, 0x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#5

AW: "FinalllyExit" gewünscht

  Alt 19. Mai 2011, 23:20
Ich halte ein Standardlabel "FinallyExit" für sehr sinnvoll, das einfach IMMER vor dem Verlassen einer Funktion/Prozedur angesprungen wird, egal was vorher auch immer passiert ist.
Sehr schwierig sollte das nicht lösbar sein
Stimmt! Das ist überhaupt nicht schwer und muss auch nicht realisiert werden, weil es das gibt.

Delphi-Quellcode:
begin
  try
    // hier kommt alles rein
  finally
    // und das hier wird vor dem Verlassen ausgeführt, egal, was vorher war.
  end;
end;
Also worum gehts hier eigentlich. Alles da, was man braucht. Und deine tolle Idee ist nichts anderes und hat dann auch die selben Nachteile, die du hier vielleicht aufführen wirst.

Dabei gibt es gar keine Nachteile.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: "FinalllyExit" gewünscht

  Alt 19. Mai 2011, 23:38
@Omata
Sofern nur ein Try-Block existiert stimmt das (habe ich ja in meinem Projekt jetzt auch so genutzt).
Aber die Struktur ist unschön, sofern in FuncA ein Fehler auftritt. Dieser ist schwerer zu finden, als wenn es keinen Try-Block gäbe.

Delphi-Quellcode:
begin
  try
    FuncA;
    FuncB;
    // hier kommt alles rein
  finally
    // Bei Fehler in FuncA geht es kommentarlos hier weiter.
    // und das hier wird vor dem Verlassen ausgeführt, egal, was vorher war.
  end;
end;
@NamenLozer
Naja, man könnte sich die Verschachtelungen sparen.
Und ein Try-Block ist ja nicht dafür da, einen Funktionsaussprung zu regeln, sondern Fehler abzufangen.
Das ist aber nicht mein Anliegen.

Man könnte sich ja auch eine abschließende Ergebnisberechnung vorstellen, z.B. Result := A+B+C , die an 10 verschiedenen Stellen notwendig werden kann.
Mit FinallyExit bräuchte man dies nur als letzte Zeile deklarieren und könnte überall einfach Exit aufrufen, das den Resultwert berechnet und den Rücksprung veranlasst.
Ich fände das übersichtlich und logisch.


@all
Aber ok, ich gebe mich geschlagen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#7

AW: "FinalllyExit" gewünscht

  Alt 19. Mai 2011, 23:42
Aber die Struktur ist unschön, sofern in FuncA ein Fehler auftritt. Dieser ist schwerer zu finden, als wenn es keinen Try-Block gäbe.
Das verstehe ich nicht. Delphi hat so einen guten Debugger, da kann doch Zeile für Zeile sehr gut überprüft werden. Vor jedem Debug-Step muss man selbst überlegen, was als nächstes passiert. Da ist nichts unübersichtlich. Sorry, ich verstehe es nicht.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#8

AW: "FinalllyExit" gewünscht

  Alt 20. Mai 2011, 00:04
Und ein Try-Block ist ja nicht dafür da, einen Funktionsaussprung zu regeln, sondern Fehler abzufangen.
Sagt wer? Try-Except ist zum Abfangen von Fehlern, ja, Try-Finally nicht unbedingt. Man verwendet Try-Finally zwar oft dazu, Ressourcen garantiert (auch im Falle eines Fehlers) wieder freizugeben, aber wie man sieht gibt es nicht nur diesen Anwendungsfall. Im Grunde heißt Try-Finally nur, dass ein bestimmter Code versuchsweise ausgeführt werden soll, und anschließend garantiert ein bestimmter anderer Code.
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

AW: "FinalllyExit" gewünscht

  Alt 19. Mai 2011, 23:26
Ich sehe einfach nicht was der Vorteil von deinem FinallyExit sein soll. Was ist der Unterschied, ob ich schreibe
Delphi-Quellcode:
procedure Foobar;
begin
  try
    {…}
    if foo=bar then
      Exit;
    {…}
  finally
    ShowMessage('foobar end')
  end;
end;
oder
Delphi-Quellcode:
procedure Foobar;
begin
  {…}
  if foo=bar then
    Exit;
  {…}
  FinallyExit:
    ShowMessage('foobar end')
end;
?
Der einzige Unterschied, den ich sehe, ist, dass in letzterem Fall eine Zeile und eine Verschachtelung spare; aber dafür kommt ein zusätzliches, redundantes Sprachfeature hinzu.

Ich mag die Dinger nicht und halte sie für wesentlich überschätzt.
Wenn man sie konsequent nutzen will, müsste man quasi jeden Befehl in einen try-Block kapseln.
Delphi-Quellcode:
A:=TA.Create;
B:=TB.Create;
try
  ...
finally
  A.Free;
  B.Free;
end;
Was aber, wenn schon TA.Create fehl schlägt???
Also müsste man dutzende try-Blöcke ineinander schachteln, um wirklich sicher zu sein?
Ich halte das für Unsinn.
Dafür gibt es ein schönes Pattern:
Delphi-Quellcode:
A := nil;
B := nil;
try
  A := TA.Create;
  B := TB.Create;
finally
  A.Free;
  B.Free;
end;
Das Tolle an Free ist nämlich, dass erst geprüft wird, ob self nil ist:
Delphi-Quellcode:
procedure TObject.Free;
begin
  if Assigned(self) then
    Destroy;
end;
Abgesehen davon löst dein FinallyExit das von dir angesprochene Problem auch nicht.

Bezüglich deines Codebeispiels:
Wieso nicht einfach so?
Delphi-Quellcode:
function TFormTestFinallyExit.Test: String;
{…}
begin
  Result := 'nix';
  S := '';
  I := 0;
  Add('begin');
  {…}
  try
    Add(' try');
    {…}
    if RadioGroupMode.ItemIndex = 6 then
    begin
      Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
      Add(IntToStr(1 div I));
    end;
    Add(' ok');
  finally
    Add(' finally');
    Add('end(finally)');
    Result := S; // redundant
    Add('end(normal)');
    Result := S;
  end;
end;
oder so:
Delphi-Quellcode:
function TFormTestFinallyExit.Test: String;
{…}
begin
  try
    Result := 'nix';
    S := '';
    I := 0;
    Add('begin');
    {…}
    try
      Add(' try');
      {…}
      if RadioGroupMode.ItemIndex = 6 then
      begin
        Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]);
        Add(IntToStr(1 div I));
      end;
      Add(' ok');
    finally
      Add(' finally');
      Add('end(finally)');
      Result := S; // redundant
    end;
  finally
    Add('end(normal)');
    Result := S;
  end;
end;

Geändert von Namenloser (19. Mai 2011 um 23:33 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:58 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