TBooleanHelper Fehler?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

TBooleanHelper Fehler?

Beitrag von theo »

Kann mal bitte jemand folgenden kurzen Code testen (Ergebnis wird der Einfachheit halber im Fenstertitel angezeigt):

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var Test:Boolean;
begin
  Test:=True;
  Caption:=Test.ToString(true);
  Test:=False;
  Caption:=Caption+' '+Test.ToString(true);
  Test:=True;
  Caption:=Caption+' '+Test.ToString(false);
  Test:=False;
  Caption:=Caption+' '+Test.ToString(false);
end;   
Ich bekomme damit "unerklärliche" Ergebnisse mit FPC 3.2.2

Hat mich gestern viel Nerven gekostet, weil ich den Fehler in meinem Code gesucht habe... :roll:

Ohne Parameter ( Test.ToString; ) zeigt er wenigstens 0 und 1 richtig an, aber der Parameter soll ja nicht den Wert setzen, sondern "UseBoolStrs" umschalten.

wp_xyz
Beiträge: 4427
Registriert: Fr 8. Apr 2011, 09:01

Re: TBooleanHelper Fehler?

Beitrag von wp_xyz »

Ein Blick in den Quellcode zeigt, dass man als Argument des Helpers ToString nicht true/false verwenden darf, sondern "TUseBoolStrs." davor setzen muss. Welch ein praxisferner Schwachsinn!

Code: Alles auswählen

Function TBOOLHELPER.ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
begin
  Result:=BoolToStr(Self,UseBoolStrs=TUseBoolStrs.True);
end;
Also:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var Test:Boolean;
begin
  Test:=True;
  Caption:=Test.ToString(TUseBoolStrs.true);
  Test:=False;
  Caption:=Caption+' '+Test.ToString(TUseBoolStrs.true);
  Test:=True;
  Caption:=Caption+' '+Test.ToString(TUseBoolStrs.false);
  Test:=False;
  Caption:=Caption+' '+Test.ToString(TUseBoolStrs.false);
end; 

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

@wp_xyz: Stimmt, da hast du voll recht, auch mit dem Schwachsinn. :lol:
Wer kommt denn auf so etwas, in der Hitze des Gefechts...

Da ist ja das alte BoolToStr(Test, true) noch kürzer zu tippen.

Man könnte sich noch fragen, warum er true/false als Parameter überhaupt akzeptiert.
Das bringt einem dann auf https://www.freepascal.org/docs-html/prog/progsu70.html , was die Sache nicht weniger mysteriös macht.

Mathias
Beiträge: 5313
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBooleanHelper Fehler?

Beitrag von Mathias »

Wäre es nicht logischer, wen die Funktion "TRUE" und "FALSE* ausgegeben würde, so wie es Writeln macht ?
"-1" & "0" ist weniger aussagekräftig.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

Mathias hat geschrieben:
Di 22. Nov 2022, 17:49
Wäre es nicht logischer, wen die Funktion "TRUE" und "FALSE* ausgegeben würde, so wie es Writeln macht ?
"-1" & "0" ist weniger aussagekräftig.
Dafür ist der Parameter ja da, nur kann man da nicht einfach "true" übergeben, sondern muss: es so machen:

Code: Alles auswählen

Test.ToString(TUseBoolStrs.true);   
Ich finde aber auch, dass "UseBoolStrs" die Standardeinstellung sein sollte, ich will ja einen String haben und nicht etwas wie ''-1'.

Mathias
Beiträge: 5313
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBooleanHelper Fehler?

Beitrag von Mathias »

Das gute alte str() kann es.

Code: Alles auswählen

var
  b: boolean = True;
  s: string;
begin
  str(b, s);
  Caption := s;   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5475
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: TBooleanHelper Fehler?

Beitrag von af0815 »

Ich nehme an, das mit den TUseBoolStrs wird benötigt, damit der Compiler die richtige Überladung finden kann. Ansonsten könnte ich das Konstrukt nicht verstehen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

af0815 hat geschrieben:
Di 22. Nov 2022, 19:02
Ich nehme an, das mit den TUseBoolStrs wird benötigt, damit der Compiler die richtige Überladung finden kann. Ansonsten könnte ich das Konstrukt nicht verstehen.
Ich verstehe das Ganze nicht.
Da sind so viele "Komplikationen" drin, dass es entweder total raffiniert oder total bescheuert ist.
z.B.

Code: Alles auswählen

{$SCOPEDENUMS ON}
   TUseBoolStrs = (False, True);
$SCOPEDENUMS OFF}

{$define TBOOLHELPER:=TBooleanHelper}
{$define TBOOLTYPE:=Boolean}
Was dabei herauskommt, ist jedenfalls aus Sicht des Users (Programmierers) suboptimal.

PascalDragon
Beiträge: 623
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: TBooleanHelper Fehler?

Beitrag von PascalDragon »

theo hat geschrieben:
Di 22. Nov 2022, 20:34
af0815 hat geschrieben:
Di 22. Nov 2022, 19:02
Ich nehme an, das mit den TUseBoolStrs wird benötigt, damit der Compiler die richtige Überladung finden kann. Ansonsten könnte ich das Konstrukt nicht verstehen.
Ich verstehe das Ganze nicht.
Da sind so viele "Komplikationen" drin, dass es entweder total raffiniert oder total bescheuert ist.
z.B.

Code: Alles auswählen

{$SCOPEDENUMS ON}
   TUseBoolStrs = (False, True);
$SCOPEDENUMS OFF}

{$define TBOOLHELPER:=TBooleanHelper}
{$define TBOOLTYPE:=Boolean}
Dies ist nötig, da FPC 9 verschiedene Boolean Typen kennt und für jeden ein entsprechender gleichartiger Helper existieren muss. Um Schreibarbeit zu sparen werden Makros verwendet.

Außerdem ist der Helper Delphi-kompatibel, weswegen seine Methoden so sind, wie sie sind: ToString mit einem Boolean-Parameter ist eine Klassenfunktionen, keine Instanzfunktion und konvertiert den übergebenen Boolean-Wert in eine Zahl und als zweiter Parameter kann ebenfalls ein TUseBoolStrs übergeben werden. Die Instanzmethode ist dann diejenige, welche nur einen Parameter vom Typ TUseBoolStrs nimmt und den Self-Wert umwandelt.
FPC Compiler Entwickler

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

@PascalDragon: Ich verstehe jetzt schon, worum es technisch geht, aber es ist ein Falle für Benutzer, welche mit der Problematik nicht vertraut sind.
Ich bin jedenfalls voll reingefallen. Ich hatte mir auch die Parameterliste nicht genauer angeschaut, weil ich es intuitiv wohl nicht für möglich gehalten hatte, dass dort ein Parameter "True" den Wert setzt. Das ist auf den ersten Blick einfach unlogisch:

Code: Alles auswählen

var Test:Boolean;
...  
Caption:=Test.ToString(true); //"true" andert den Wert des Resultats, statt den von BoolStrs.
Kann man das nicht anders lösen?
Wenn man bei der Klassenfunktion keinen Standard angeben würde, käme man da auch nicht mit einem Boolean Parameter davon und der Compiler würde einen darauf aufmerksam machen. Also so

Code: Alles auswählen

  TBooleanHelper = Type Helper for Boolean
  public
  ...
    Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs): string; overload; inline; static;
statt so:

Code: Alles auswählen

  TBooleanHelper = Type Helper for Boolean
  public
  ...
    Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
Oder denke ich falsch?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5475
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: TBooleanHelper Fehler?

Beitrag von af0815 »

Ich nehme an, das ist die Killerphrase:
Außerdem ist der Helper Delphi-kompatibel, weswegen seine Methoden so sind, wie sie sind:
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

af0815 hat geschrieben:
Mi 23. Nov 2022, 11:51
Ich nehme an, das ist die Killerphrase:
Außerdem ist der Helper Delphi-kompatibel, weswegen seine Methoden so sind, wie sie sind:
Schon, aber der Verzicht auf einen Standardwert in der Klassenfunktion (Wo wird diese absichtlich benutzt, ausser innerhalb von TBooleanHelper?), wäre vllt. gerade noch "drin". :wink:

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5475
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: TBooleanHelper Fehler?

Beitrag von af0815 »

Ist bei Delphi so deklariert

Code: Alles auswählen

function BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string;
Quelle: https://docwiki.embarcadero.com/Librari ... .BoolToStr
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 9568
Registriert: Mo 11. Sep 2006, 19:01

Re: TBooleanHelper Fehler?

Beitrag von theo »

af0815 hat geschrieben:
Mi 23. Nov 2022, 13:10
Ist bei Delphi so deklariert

Code: Alles auswählen

function BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string;
Quelle: https://docwiki.embarcadero.com/Librari ... .BoolToStr
Das ist wieder was anderes. Das ist die normale Funktion in sysstr(h).inc.. Von der sprechen wir hier nicht.
Das Problem ist beim Helper Typen in syshelph.inc resp. syshelpb.inc

Code: Alles auswählen

  {$SCOPEDENUMS ON}
    TUseBoolStrs = (False, True);
  {$SCOPEDENUMS OFF}

  TBooleanHelper = Type Helper for Boolean
  public
    Class Function Parse(const S: string): Boolean; inline; static;
    Class Function Size: Integer; inline; static;
    Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
    Class Function TryToParse(const S: string; out AValue: Boolean): Boolean; inline; static;
  Public
    Function ToInteger: Integer; inline;
    Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
  end;    
Also es geht nicht um
BoolToStr(B,true);
sondern um
B.ToString(true);

PascalDragon
Beiträge: 623
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: TBooleanHelper Fehler?

Beitrag von PascalDragon »

theo hat geschrieben:
Mi 23. Nov 2022, 12:12
af0815 hat geschrieben:
Mi 23. Nov 2022, 11:51
Ich nehme an, das ist die Killerphrase:
Außerdem ist der Helper Delphi-kompatibel, weswegen seine Methoden so sind, wie sie sind:
Schon, aber der Verzicht auf einen Standardwert in der Klassenfunktion (Wo wird diese absichtlich benutzt, ausser innerhalb von TBooleanHelper?), wäre vllt. gerade noch "drin". :wink:
Beide Methoden haben einen Standardwert:

Code: Alles auswählen

  TBooleanHelper = Type Helper for Boolean
  public
    { ... }
    Class Function ToString(const AValue: Boolean; UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline; static;
    { ... }
  Public
    { ... }
    Function ToString(UseBoolStrs: TUseBoolStrs = TUseBoolStrs.False): string; overload; inline;
  end;
Und außerdem kann niemand sagen, wo die Klassenmethode verwendet wird, da sie öffentlich ist, das heißt jeder kann sie nutzen.
theo hat geschrieben:
Mi 23. Nov 2022, 09:58
Kann man das nicht anders lösen?
Wenn man bei der Klassenfunktion keinen Standard angeben würde, käme man da auch nicht mit einem Boolean Parameter davon und der Compiler würde einen darauf aufmerksam machen.
Nein, da das nicht Delphi-kompatibel wäre. Die Helper existieren rein wegen Delphi.
FPC Compiler Entwickler

Antworten