Existenz von Methoden mittels $IFDEF abfragen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Ekkehard
Beiträge: 67
Registriert: So 12. Feb 2023, 12:42
OS, Lazarus, FPC: Windows Lazarus 3.6, FPC 3.2.2
CPU-Target: 64-Bit
Wohnort: Hildesheim

Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Ekkehard »

Hallo Ihr Lieben,
kann Existenz von Klassen-Methoden mittels $IFDEF abfragen?
Das Problem ist folgendes:
Wenn ich etwas lokal an vorhandenen Fremdmodulen ändere, also zusätzliche Methoden einführe und verwende, um bespw. etwas zu optimieren, dann gibt es diese Methoden in der aktuellen Distribution der Fremdmodule nicht. Wenn jemand jetzt meinen Code nimmt und compiliert, stoppt der Compiler und sagt: Methode XYZ existiert nicht.
Kann man das mittels $IFDEF abfragen?

Also ein Beispiel:

Code: Alles auswählen

// Im Fremdmodul
type
  TBeispiel = class(TObject)
  public
    procedure Langsam; // Existiert in der Distribution
    procedure  Schnell; // Existiert nur bei mir, in einigen Wochen dann auch in der Distribution
  end;

// In meinem Code dann
var
  Beispiel : TBeispiel;
(...)
{$IFDEF TBeispiel.Schnell}
  Beispiel.Schnell;
{$ELSE}
  Beispiel.Langsam;
{$ENDIF}
(...)
Kann man sowas machen?
Im Moment schreibe ich Kommentare und der Code-Verwender muss dann händisch ändern

Code: Alles auswählen

  Beispiel.Schnell; // Wenn der Compiler hier meckert, diese Zeile aus- und die nächste Zeile einkommentieren!
//  Beispiel.Langsam;
und es wäre schön, wenn man sich das sparen könnte.
Vielen Dank und schönen Feiertag!
Gruß Ekkehard

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

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von theo »

Du kannst die Definition in deinen Projekteinstellungen setzen, dann brauchst du deinen Code nicht anpassen.

Code: Alles auswählen

{$IFDEF Schnell}
  Caption:='Schnell';
{$ELSE}
  Caption:='Langsam';
{$ENDIF}   
Dateianhänge
lazdef.png
lazdef.png (146.24 KiB) 3493 mal betrachtet

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Sieben »

$IF DECLARED(symbol) sollte das wohl leisten können, unterliegt aber wohl immer noch Einschränkungen, die es für das hier gezeigte Beispiel leider (noch) nicht verwendbar machen, siehe hier (bzw genauer hier).
Bliebe immer noch der von Theo beschriebene 'manuelle' Weg.

Ekkehard
Beiträge: 67
Registriert: So 12. Feb 2023, 12:42
OS, Lazarus, FPC: Windows Lazarus 3.6, FPC 3.2.2
CPU-Target: 64-Bit
Wohnort: Hildesheim

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Ekkehard »

Dann erstmal danke für die Antworten.
Das selbsterzeugte Define ist natürlich eine Lösung, vermutlich die Einfachste.
Die Sache mit dem "declared()" werde ich mir mal ansehen, denn das kannte ich bislang nicht.
Gruß Ekkehard

charlytango
Beiträge: 1088
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von charlytango »

Ekkehard hat geschrieben: Do 3. Okt 2024, 12:16 Wenn ich etwas lokal an vorhandenen Fremdmodulen ändere, also zusätzliche Methoden einführe und verwende, um bespw. etwas zu optimieren, dann gibt es diese Methoden in der aktuellen Distribution der Fremdmodule nicht. Wenn jemand jetzt meinen Code nimmt und compiliert, stoppt der Compiler und sagt: Methode XYZ existiert nicht.
kann sein, dass ich das Problem nicht verstehe:
Zuerst gilt es zu definieren, was du unter "Fremdmodul" verstehst.

Ich gehe mal davon aus dass du ein fremdes Package(=FP) meinst, das z.B. per Lazarus oder OPM installiert werden kann.

Wenn du so ein Package ableitest ud deine eigenen Methoden entwickelst, hast du ja ein völlig neues Objekt, das "bloß" das FP als Vorfahren hat. Ohne das installierte FP kann man dein Projekt ja nicht kompilieren.
Gleiches (also das FP installieren) muss auch jemand machen, der deinen Code benutzt.

Sollte das FP nicht per Lazarus bzw OPM installierbar sein, musst du es eben mitliefern (wie es einige Open Source Programme tun, besonders wenn es auf bestimmte Versionen ankommt) oder informieren wo man es beziehen kann.

Das ist aus meiner Sicht ein völlig übliches Verhalten. Wo also ist das Problem?

Dazu sollten keinerlei DEFINE Anweisungen nötig sein

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von fliegermichl »

Das funktioniert tatsächlich ohne jedes $define.
Der folgende Code gibt Langsam aus, wenn die procedure schnell auskommentiert ist, ansonsten "Schnell"

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    //procedure schnell;
    procedure Langsam;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  {$if declared(Schnell)}
   schnell;
  {$else}
   langsam;
  {$endif}
end;

(*
procedure TForm1.schnell;
begin
  showmessage('Schnell!');
end;
*)

procedure TForm1.Langsam;
begin
  showmessage('Langsam!');
end;

end.
Was allerdings etwas verwirrend ist, Schreibe ich

Code: Alles auswählen

 {$if declared(TForm1.Schnell)}
 ...
erhalte ich einen Compilerfehler. unit1.pas(35,7) Error: Evaluating a conditional compiling expression

Edit: PascalDragon erklärte hier im internationalen Forum, dass declared keine Punkte im Bezeichnernamen akzeptiert. Ist auf der ToDo Liste und die scheint lang zu sein.

Ekkehard
Beiträge: 67
Registriert: So 12. Feb 2023, 12:42
OS, Lazarus, FPC: Windows Lazarus 3.6, FPC 3.2.2
CPU-Target: 64-Bit
Wohnort: Hildesheim

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Ekkehard »

dass declared keine Punkte im Bezeichnernamen akzeptiert
So habe ich das auch verstanden und deshalb ist das auch keine Lösung für mein Problemchen.

Ekkehard
Beiträge: 67
Registriert: So 12. Feb 2023, 12:42
OS, Lazarus, FPC: Windows Lazarus 3.6, FPC 3.2.2
CPU-Target: 64-Bit
Wohnort: Hildesheim

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Ekkehard »

charlytango hat geschrieben: Do 3. Okt 2024, 23:27 kann sein, dass ich das Problem nicht verstehe:
(...)
Ich gehe mal davon aus dass du ein fremdes Package(=FP) meinst, das z.B. per Lazarus oder OPM installiert werden kann.
(...)
Sollte das FP nicht per Lazarus bzw OPM installierbar sein, musst du es eben mitliefern (...).

Das ist aus meiner Sicht ein völlig übliches Verhalten. Wo also ist das Problem?
Hallo CharlyTango,
fast alles richtig was Du schreibst.
Es handelt sich (kein Geheimnis) um die Komponente LazMapViewer, die ich in meinem (schon häufiger erwähnten) Projekt LazQuadTree (welches ich bald als OpenSource veröffentlichen werde) verwende und da dann konkret in einer Demo-Anwendung dazu.
Die Komponente TMapView verwaltet intern auf "GPSLayers" GPS-Objekte, die diverse Symbole darstellen können. Das Problem dabei, wenn man sehr viele davon einträgt (bspw. 95.000) dauert das Löschen quälend lange, weil die Löschmethode ein Feuerwerk von Aktionen abbrennt, die hier nicht benötigt werden, aber endlos Zeit kosten.
Das wäre nicht schlimm, aber es sieht für den einfachen Benutzer der Demo so aus, als ob meine Komponente der Störenfried ist und das System ausbremmst - und das möchte ich nicht unkommentiert so stehen lassen.
Einer der Entwickler/Betreuer (User wp_xyz in diesem Forum) war so lieb, dieses Problem dahingehend zu lösen, dass er in die Komponente eine Methode eingebaut hat, die das Löschen schnellstens erledigt.
Diese Methode hat mit der alten Methode nichts zu tun, sondern ist, wie in meinem Eingangsbeispiel, einfach was Neues. Leider ist diese schöne Änderung noch nicht in der aktuellen Distribution vorhanden, ja noch nicht einmal in den Downloads, und daran wird sich aus verständlichem und nachvollziehbarem Zeitmangel auch nicht schnell etwas ändern.
Jetzt besteht mein Problem darin, eine lauffähige Demo zu bauen, die ohne den Benutzer zu nerven, die beste verfügbare Lösung zu verwendet. Die bestünde darin, mittels eines Compiler-Befehls zu prüfen, ob die schnelle Variante installiert ist (was in einigen Wochen/Monaten dann der Fall ist) oder eben nur die langsame.
Natürlich könnte ich die veränderte Version des MapViewers mitliefern, das ist aber nicht zielführend, denn niemand will sich kurz eine Demo ansehen und dafür zuvor installierte Drittkomponenten (mit Änderungen aus dritter Hand und im laufenden Betrieb) aktualisieren.

Viel schöner wäre im Übrigen die Lösung die Komponente abzuleiten, die "böse" Methode zu überschreiben und dann in meiner Demo diese Variante zu instantiieren. Leider geht das nicht, weil die Entwickler der Komponente (das bedaure ich, ist aber deren durchaus auch begründete Entscheidung gewesen) sehr restriktiv mit den Schlüsselworten "virtual" und "protected" umgehen und man/ich da einfach nicht rankomme.

Ich werde jetzt den Weg mittels eines Defines gehen und eine sichtbare Warnung einbauen, die dann bei Bedarf umgangen werden kann, wenn die Voraussetzungen dafür vorhanden sind.

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

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von af0815 »

Ich verstehe (noch immer) nicht warum du da so komisch umschalten willst.

Entweder hast du den adaptierten Code für die Komponente oder nicht. Wenn du jetzt das Demo baust, warum nicht mit dem optimalen Stand der Komponente. Der Code liegt in einem öffentlichen SVN auf Sourceforge und in Rev. 9471 wurde das ClearAll hinzugefügt. Warum nimmst du nicht den Stand von dort ? Der ist jederzeit herunterladbar, da brauche ich kein OPM etc.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

BeniBela
Beiträge: 321
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von BeniBela »

wie wäre das?

Code: Alles auswählen

type
  TBeispiel = class(TObject)
  public
    procedure Langsam; // Existiert in der Distribution
    procedure Schnell; // Existiert nur bei mir, in einigen Wochen dann auch in der Distribution
  end;

// In meinem Code dann
var
  Beispiel : TBeispiel;

...

  with beispiel do
  {$IF declared(Schnell)}
    Schnell;
  {$ELSE}
    Langsam;
  {$ENDIF}

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

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von theo »

@BeniBela
Das geht tatsächlich! :D
Aber naja, das hat so einen Beigeschmack von "undokumentiertem Verhalten".
Ich weiss nicht, ob ich das wirklich einsetzen wollte.

Aber Respekt! :lol:

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1651
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von fliegermichl »

BeniBela hat geschrieben: Fr 4. Okt 2024, 13:03 wie wäre das?
Geht nicht. defined liefert dann immer false.

Edit: Geht doch ich hatte defined anstatt declared geschrieben.

Sieben
Beiträge: 292
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von Sieben »

Yep, das ist wirklich ein feiner Trick, wäre schön, wenn PascalDragon vielleicht noch was dazu sagen könnte. Wenn ich den Fragesteller richtig verstehe, wird das aber eh nur für eine absehbare und begrenzte Zeit benötigt - so lange kann man wohl auch mal auf undokumentiertes Verhalten bauen, zumindest bis zur nächsten Compiler-Version.

PascalDragon
Beiträge: 963
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: Existenz von Methoden mittels $IFDEF abfragen

Beitrag von PascalDragon »

Gute Frage, ob man das als beabsichtigtes Verhalten ansehen kann. Es ergibt Sinn, da der Compiler einfach nur den Stapel an Symboltabellen durchgeht (und innerhalb eines with ist die Symboltabelle des Symbols im with eben auch Teil des Stapels), aber wie gesagt keine Ahnung, ob das im Sinne des Erfinders ist. 🤔
FPC Compiler Entwickler

Antworten