AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE Verträge für Delphi / Design by Contract
Thema durchsuchen
Ansicht
Themen-Optionen

Verträge für Delphi / Design by Contract

Offene Frage von "jaenicke"
Ein Thema von dominikkv · begonnen am 26. Jun 2013 · letzter Beitrag vom 29. Nov 2013
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Stevie
Stevie

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

AW: Verträge für Delphi / Design by Contract

  Alt 27. Jun 2013, 11:45
Was die Laufzeit Auswertung angeht, kann man das über AOP machen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
D-User

Registriert seit: 19. Dez 2006
Ort: NRW
56 Beiträge
 
#12

AW: Verträge für Delphi / Design by Contract

  Alt 27. Jun 2013, 20:58
für ein Vorbedingungs- Nachbedingungs- Zwischenbedingungs Sonstiges
Kontroll-Konstrukt kann man schön methodenlokale Prozeduren/
funktionen nutzen( die nat. ggf andere Methoden aufrufen).
Je nach Lage der methodenlokalen Variablen zur o.a. Prozedur/Fkt
kann man dann auf diese Variablen und die Parameter wie gewünscht zugreifen
oder aber aus dem Zugriff raushalten.

Mal so auf die Schnelle:

Delphi-Quellcode:
type
  TMyCheckSituation = (sVB, sSit1, sNB );

procedure TForm3.Mach(aInt: integer);
var
  TestMe: integer;

  procedure Chk( const MySituation: TMySituation);
  begin
    case MySituation of
      sVB: if (aInt<8) and ( TestMe<0) then // Testfehler!:
               // irgendwie Fehlerbedingung händeln, z.B: except.
               raise Exception.Create('Loud Cry');
      sSit1: ;// Check für Sit.1
      sNB: ;// Nachbedingungsckeck;
    end;
    DoMyGeneralTest;
  end;

var
  DontTestMe: integer;
begin
  Chk(sVB); // Situationstest Vorbedingung

  DontTestMe := 1;

  MachWas;
  TestMe := DontTestMe;

  {$REGION 'InnerCheck SaubereMitte'}
  Chk(sSit1); // Situationstest Situation 1
  {$ENDREGION}

  MachNochWas;

  Chk(sNB); // NachBedingung
end;
  Mit Zitat antworten Zitat
Namenloser

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

AW: Verträge für Delphi / Design by Contract

  Alt 28. Jun 2013, 03:27
Nur so eine Idee, die mir gerade kam, aber vielleicht könnte man auch records dafür missbrauchen.
Z.B.:
Delphi-Quellcode:
type
  EContractViolation = class(Exception)
  end;

  TObjectNotNil = record
  private
    FObj: TObject;
  public
    operator Implicit(const Obj: TObject): TObjectNotNil;
    operator Implicit(const Obj: TObjectNotNil): TObject;
  end;

operator TObjectNotNil.Implicit(const Obj: TObject): TObjectNotNil;
begin
  if not Assigned(Obj) then
    raise EContractViolation.Create("Reference must not be nil");
  Result.FObj := Obj;
end;

operator TObjectNotNil.Implicit(const Obj: TObjectNotNil): TObject;
begin
  Result := Obj.FObj;
end;

procedure DoSomethingWithObject(Obj: TObjectNotNil);
begin
  Obj.{...}
end;

DoSomethingWithObject(nil);
// => EContractViolation
Keine Ahnung, ob Delphi das Konstrukt überhaupt zulässt... ich hatte mit dem Implicit-Operator unter Delphi 2006 schon bei harmloseren Sachen Probleme, aber bei 2006 waren überladene record-Operatoren generell buggy.
Und natürlich ist das so, wie es hier steht, viel zu aufgebläht... aber vielleicht könnte man ja irgendwie einen Preprocessor schreiben, der den Code vor der Kompilierung generiert, oder vielleicht kann man mit Generics noch was rausholen.

Wahrscheinlich ist das alles nicht wirklich praktikabel, aber ich wollte die Idee gerade mal niederschreiben...
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.590 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: Verträge für Delphi / Design by Contract

  Alt 28. Jun 2013, 06:35
Keine Ahnung, ob Delphi das Konstrukt überhaupt zulässt... ich hatte mit dem Implicit-Operator unter Delphi 2006 schon bei harmloseren Sachen Probleme, aber bei 2006 waren überladene record-Operatoren generell buggy.
Ja, das funktioniert so, ohne es gerade testen zu können, abgesehen von den falschen Stringdelimitern und dass das class vor operator fehlt. Auf diese Weise habe ich in ein Dictionary automatisch Lowercase Strings als Key gebracht.

Das funktioniert so aber auch schon mit Delphi 2006 würde ich behaupten, auch wenn ich das gerade nicht testen kann...
Ich habe dort schon relativ viel mit Klassenoperatoren gemacht und hatte damit keine Probleme.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: Verträge für Delphi / Design by Contract

  Alt 28. Jun 2013, 07:59
Das geht auch mit einem generischen Record, so wie in diesem Blog gezeigt wird (für C#).

Kleiner Unterschied bei dieser Lösung allerdings ist, dass im Falle von nil die Exception vor dem Aufruf und nicht danach bzw innerhalb der aufgerufenen Methode geraised wird.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#16

AW: Verträge für Delphi / Design by Contract

  Alt 28. Jun 2013, 18:18
Solche Lösung sind zwar gut gegen Nullpointer, biete aber keine statische Analysefähigkeit.

Das ist es, was die Design-by-Contract so wertvoll macht. Anfangs- und Endzustände sowie Invarianten checken kann man zwar manuell machen. Aber schon mit dem (erzwungenen) Vererbungen der "Contracts" wird ohne Compiler-Unterstützung kniffelig bis unmöglich.
Es ist wie mit der Typen: Wenn es nicht erzwungen wird, ist nicht so viel Wert.


Das Argument mit dem Halteproblem kann ich nicht nachvollziehen. Abgesehen von dem begrenzten Speicher sollte es problemlos möglich sein, eine Turingmaschine zu realisieren. Schließlich bieten die Contracts keine Aussage über die Laufzeit.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Namenloser

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

AW: Verträge für Delphi / Design by Contract

  Alt 28. Jun 2013, 18:50
Das Argument mit dem Halteproblem kann ich nicht nachvollziehen. Abgesehen von dem begrenzten Speicher sollte es problemlos möglich sein, eine Turingmaschine zu realisieren. Schließlich bieten die Contracts keine Aussage über die Laufzeit.
Doch, das ist theoretisch schon ein Problem. Angenommen, dein Contract wäre, dass ein kryptographischer Hash des Parameters nicht 0 sein darf. Also z.B. SHA1(Parameter) <> 0. Viel Spaß dabei, zur Compilezeit auszuwerten, welche Werte erlaubt sind.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#18

AW: Verträge für Delphi / Design by Contract

  Alt 29. Jun 2013, 17:46
Doch, das ist theoretisch schon ein Problem. Angenommen, dein Contract wäre, dass ein kryptographischer Hash des Parameters nicht 0 sein darf. Also z.B. SHA1(Parameter) <> 0. Viel Spaß dabei, zur Compilezeit auszuwerten, welche Werte erlaubt sind.
Hashen zur Compilezeit ist nicht wirklich unmöglich (oder auch nur unüblich).

Aber ich glaube, mir ist eben des Halteproblemargument aufgegangen:
Es ist nicht aufgrund des Halteproblems nicht möglich, herauszubekommen, ob zwei Prozeduren (~> Turingmaschinen) das selbe Ergebnis liefern.
Also müsst der Programmierer im Zweifelsfall vor dem Aufruf explizit auf die gleiche Bedingung prüfen, die in dem Contract spezifiziert ist. Das wäre unschön (keine Perfektion).


Ich glaube aber, dass wirklich praktisch auftretende Problem ist, dass Contracts nur eine weitere Spezifikationen sind,
die unvollständig oder schlicht gänzlich falsch sein können.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Namenloser

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

AW: Verträge für Delphi / Design by Contract

  Alt 30. Jun 2013, 23:57
Doch, das ist theoretisch schon ein Problem. Angenommen, dein Contract wäre, dass ein kryptographischer Hash des Parameters nicht 0 sein darf. Also z.B. SHA1(Parameter) <> 0. Viel Spaß dabei, zur Compilezeit auszuwerten, welche Werte erlaubt sind.
Hashen zur Compilezeit ist nicht wirklich unmöglich (oder auch nur unüblich).
Darum geht es aber nicht. Der Parameter ist ja dynamisch. Sagen wir, der Parameter wäre der Rückgabewert einer Funktion, die alles zwischen 0 und MAXINT zurückliefern kann. Wie soll der Compiler feststellen, ob dabei was herauskommen kann, was von der kryptographischen Hashfunktion auf die 0 abgebildet wird?
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#20

AW: Verträge für Delphi / Design by Contract

  Alt 1. Jul 2013, 15:05
Darum geht es aber nicht. Der Parameter ist ja dynamisch. Sagen wir, der Parameter wäre der Rückgabewert einer Funktion, die alles zwischen 0 und MAXINT zurückliefern kann. Wie soll der Compiler feststellen, ob dabei was herauskommen kann, was von der kryptographischen Hashfunktion auf die 0 abgebildet wird?
Genau darum geht es letzten Endes:

Du hast eine Funktion A die gemäß Contract einen beliebigen Wert zwischen 1 und 10 zurückliefern kann.
Du hast eine andere Funktion B, die einen Parameter hat der per Contract nur Werte zwischen 0 und 5 annehmen darf.

Wenn Du nun eine Variable aus A füllst und in B reinwirfst, dann kann Dir der Compiler eine Warnung um die Ohren hauen das dieses Ding Deinen Contract verletzt.

Du kannst nun entweder
* die Fälle von 6-10 mit einer Sonderbehandlung bedienen und nur die Werte bis 5 in B reinwerfen
* oder aber sicherstellen das A nur noch Werte zurückgibt die B auch annehmen kann
* oder aber dafür sorgen das B auch Werte bis 10 verträgt.

Machst Du nichts davon und ignorierst die Warnung einfach, DANN wirst Du möglicherweise zur Laufzeit Probleme bekommen.

Es geht ja nicht darum, vollumfänglich zur Compilezeit sicherzustellen das da nie was falsches reingegeben wird. Es geht darum, das Dir der Compiler vorab ausreichend Hinweise gibt wo es eben potentiell zu Contractverletzungen und damit zu möglichen Fehlerquellen kommen kann. So kann man nämlich vorher mögliche Problemfälle analysieren, automatisch testen und muss nicht erst warten bis es draussen irgendwo wegen einer seltsamen Eingabe mal in einem Edge-Case zu einem Fehler kommt.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      

 

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 04:33 Uhr.
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