Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variablen in Stringliteral inlinen (https://www.delphipraxis.net/203319-variablen-stringliteral-inlinen.html)

QuickAndDirty 5. Feb 2020 14:17

Delphi-Version: 10.3 Rio

Variablen in Stringliteral inlinen
 
gabs das feature nicht mal
Delphi-Quellcode:
var Mark := '1';
var Pfennig := '20';
Showmessage('sie haben noch $Mark und $Pfennig.');
Nur eben ohne dollar sondern mit irgendwas anderem?

Klaus01 5. Feb 2020 14:25

AW: Variablen in Stringliteral inlinen
 
Delphi-Quellcode:
var Mark := '1';
var Pfennig := '20';
Showmessage(format('sie haben noch %s Mark und %s Pfennig.',[Mark, Pfenning]));

QuickAndDirty 5. Feb 2020 14:28

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Klaus01 (Beitrag 1456750)
Delphi-Quellcode:
var Mark := '1';
var Pfennig := '20';
Showmessage(format('sie haben noch %s Mark und %s Pfennig.',[Mark, Pfenning]));

Also erinnere ich mich falsch und es gab keine Änderung am Stringliteral in dieser Hinsicht?

Klaus01 5. Feb 2020 14:31

AW: Variablen in Stringliteral inlinen
 
Es geht auch noch so:

Delphi-Quellcode:
Showmessage('sie haben noch '+Mark+' Mark und '+Pfennig+' Pfennig.');
Aber mit $ oder ähnlichen Zeichen ist mir nichts bekannt - in Delphi.

Grüße
Klaus

QuickAndDirty 5. Feb 2020 14:45

AW: Variablen in Stringliteral inlinen
 
Ich dachte da wäre was gewesen, weil mir gerade aufgefallen sind das so viele schöne Dinge in die Delphi Sprache gekommen sind.

Uwe Raabe 5. Feb 2020 15:22

AW: Variablen in Stringliteral inlinen
 
Ich bezweifle, daß sowas irgendwann überhaupt implementiert wird. Das würde ja jeglichen Code, der solche Strings (unabhängig von $ oder was anderem) bereits verwendet, dann nicht mehr funktionieren würde.

dummzeuch 5. Feb 2020 15:30

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1456757)
Ich bezweifle, daß sowas irgendwann überhaupt implementiert wird. Das würde ja jeglichen Code, der solche Strings (unabhängig von $ oder was anderem) bereits verwendet, dann nicht mehr funktionieren würde.

Naja, man koennte ja einen neuen Stringtyp einführen:

Delphi-Quellcode:
const
  blub = 'blub';
  bla: ExtendedStrings = 'bla $blub';
oder sowas.

Uwe Raabe 5. Feb 2020 15:46

AW: Variablen in Stringliteral inlinen
 
OK, dann sprechen wir aber formell auch über ExtendedStrings-Literale und nicht über String-Literale :)

freimatz 5. Feb 2020 16:27

AW: Variablen in Stringliteral inlinen
 
War sowas nicht in php oder awk?

Stevie 5. Feb 2020 17:38

AW: Variablen in Stringliteral inlinen
 
Nein, es gibt keine String interpolation mit Variablennamen in Delphi. Nur die von Format akzeptierten Platzhalter.

QuickAndDirty 5. Feb 2020 20:01

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von freimatz (Beitrag 1456772)
War sowas nicht in php oder awk?

Es ist in PHP und in Perl so!

Code:
$Mark = 3;
$Pfennig = 40;
$Variable1 = "Das sind $Mark Mark und $Pfennig Pfennig";
In Javascript wird es so gemacht
Code:
var a = '5';
var b = '10';
console.log(`Das sind ${Mark} Mark und ${Pfennig} Pfennig`);
Die Akzente sind außerdem Multiline-String-Literale in Javascrip!

Ich dachte wirklich wir haben das auch...Aber ist wohl alzheimer

QuickAndDirty 5. Feb 2020 20:03

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Stevie (Beitrag 1456782)
Nein, es gibt keine String interpolation mit Variablennamen in Delphi. Nur die von Format akzeptierten Platzhalter.

Menno sogar Swift hat das!
Es wäre so gut wenn die das einbauen.
Cotlin, Dart, Swift und C# 6.0 alle haben es

C#
Code:
// C# 6.0
var apples = 4;
var bananas = 3;
Console.WriteLine($"I have {apples} apples");
Console.WriteLine($"I have {apples + bananas} fruit");

Stevie 5. Feb 2020 23:38

AW: Variablen in Stringliteral inlinen
 
Im Hinblick auf Lokalisierung (resourcestrings) ist das gar nicht mehr so toll, wie es zuerst erscheinen mag. Denn man kann string Interpolation nur dort nutzen, wo auch die im String referenzierten Symbole zugänglich sind. Und in aller Regel hat man dort, wo resourcestrings deklariert werden keinen Zugriff auf diverse Variablen oder Properties.

Es gibt auch Entwickler, die String Interpolation sogar für schlecht halten.

QuickAndDirty 6. Feb 2020 11:33

AW: Variablen in Stringliteral inlinen
 
Nun Ich generiere delphi code für eine include datei...jetzt mit format('Bla%d blabla%s '[x,y]) :(
Glaube mir die Ausgabe mit string interpolation hätte den Quellcode in den strings sicher leichter manipulierbar und umstellbar gemacht.
Ich sage ja nicht das es der Heilige Gral ist, frei von jedwedem Nachteil.

Dennoch hätte Stringinterpolation mir bei der Aufgabe echt was gebracht(leichte Umstellbarkeit des Codes in den Strings)
Das andere Übel ist die häßliche art und weise wie Einzelhochkomma escaped werden....
Sowohl QuotedString('TADA') als auch ''''''''''''''''''' sind keine sehr befriedigende Art sowas zu machen.
Auch ein Multiline String literal wäre schon schön für diese Aufgabe gewesen.

Ich möchte dazu sagen, fasst das bitte nicht als nörgeln auf. Ich habe alles was ich hinbekommen wollte mit Delphi hinbekommen...
Es geht mir eher um nicetohaves.
JA, ich will von Embarcadero verwöhnt werden. ^^
Zumindest würde es mich freuen :)

freimatz 6. Feb 2020 12:51

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1456787)
Menno sogar Swift hat das!
Es wäre so gut wenn die das einbauen.
Cotlin, Dart, Swift und C# 6.0 alle haben es

Es wäre schlecht wenn die das einbauen. Das verleitet zu QuickAndDirty-Code :-P

(Bei uns wurde eh solcher Code von der Person, die für Übersetzungen zuständig ist, verboten.)

Dennis07 6. Feb 2020 14:51

AW: Variablen in Stringliteral inlinen
 
Könntest dir nen IDE-Plugin dafür bauen, das das im Editor mit nem Rechtsklick oder so parst. Aber ansonsten sehe ich da nicht viel Möglichkeit.
Was jedoch ginge, wäre so etwas für Klassenfelder zu machen, da diese über die RTTI abrufbar sind. Globale oder lokale Variablen/Konstanten allerdings wirst du so nicht verarbeiten können.

TurboMagic 6. Feb 2020 19:33

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von freimatz (Beitrag 1456831)
Zitat:

Zitat von QuickAndDirty (Beitrag 1456787)
Menno sogar Swift hat das!
Es wäre so gut wenn die das einbauen.
Cotlin, Dart, Swift und C# 6.0 alle haben es

Es wäre schlecht wenn die das einbauen. Das verleitet zu QuickAndDirty-Code :-P

(Bei uns wurde eh solcher Code von der Person, die für Übersetzungen zuständig ist, verboten.)

Denke ich auch und man müsste sowas evtl. auch öfters mal "escapen" :-(

freimatz 7. Feb 2020 10:33

AW: Variablen in Stringliteral inlinen
 
Hm, mir kommt gerade eh der Gedanke, dass Texte eigentlich gar nicht in Code gehören.
Bei uns gibt es allenfalls Texte auf englisch die bei Exceptions erscheinen, die der Anweder eh nicht sehen sollte.

Dennis07 7. Feb 2020 10:43

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von freimatz (Beitrag 1456902)
Hm, mir kommt gerade eh der Gedanke, dass Texte eigentlich gar nicht in Code gehören.
Bei uns gibt es allenfalls Texte auf englisch die bei Exceptions erscheinen, die der Anweder eh nicht sehen sollte.

Davon mal ganz abgesehen :-D

Uwe Raabe 7. Feb 2020 11:34

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von freimatz (Beitrag 1456902)
Hm, mir kommt gerade eh der Gedanke, dass Texte eigentlich gar nicht in Code gehören.

Umgekehrt gehört Code (hier Variablennamen) auch nicht in String-Literale.

dummzeuch 7. Feb 2020 13:55

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1456911)
Zitat:

Zitat von freimatz (Beitrag 1456902)
Hm, mir kommt gerade eh der Gedanke, dass Texte eigentlich gar nicht in Code gehören.

Umgekehrt gehört Code (hier Variablennamen) auch nicht in String-Literale.

+1

Wobei das eigentlich auch für die Platzhalter in Format-Strings gilt. Wenn der Übersetzer dabei einen Fehler macht, stürzt das Programm ab:

Delphi-Quellcode:
 s := Format(_('Result is %d'), [Res]);

Und der Übersetzer vertippt sich:
'Ergebnis ist %f'

Bumm!

himitsu 7. Feb 2020 14:21

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von dummzeuch (Beitrag 1456927)
Und der Übersetzer vertippt sich:
'Ergebnis ist %f'
Bumm!

Texte mit Formatierungen aus anderen Quellen sind immer nett, wenn das Programm plötzlich verreckt.
(Übersetzung/Datenbank wo Texte durch user bearbeitet oder über eine Synchronisierung/Update nachgeladen werden)

Drum hab ich bei uns das Format überschrieben/überdeckt.
Der Code muß nur in eine Unit die immer nach den SysUtils eingebunden wird.

Wenigstens "etwas" anzeigen und das Programm nicht abkratzen lassen.
Delphi-Quellcode:
function Format(const FormatStr: string; const Args: array of const): string;
begin
  try
    Result := SysUtils.Format(FormatStr, Args);
  except
    {Meldung ins Log, wenn sowas vorhanden}
    Result := FormatStr; // oder Result := '[ERR] ' + FormatStr;
  end;
end;
Oder zumindestens dem Entwickler etwas helfen, damit man gleich sieht bei welchem "kompletten" String es knallt.
Delphi-Quellcode:
function Format(const FormatStr: string; const Args: array of const): string;
begin
  try
    Result := SysUtils.Format(FormatStr, Args);
  except
    on E: Exception do begin
      E.Message := 'Fehler in Format-String >>' + FormatStr + '<<' + sLineBreak + sLineBreak + E.Message;
      raise;
    end;
  end;
end;
Und das Gleiche für die Variante mit den FormatSettings.

Alternativ verwendet man niemals Format, sondern ruft eine eigene MyFormat auf.

Uwe Raabe 7. Feb 2020 14:35

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von dummzeuch (Beitrag 1456927)
Wenn der Übersetzer dabei einen Fehler macht, stürzt das Programm ab

Da braucht er nicht mal einen Fehler machen. Es genügt, wenn er den Satzbau umstellt und sich dadurch die Reihenfolge der Parameter ändert. Deswegen sollte man in solchen Fällen auf die Index-Funktionalität in Format zurückgreifen.

himitsu 7. Feb 2020 14:41

AW: Variablen in Stringliteral inlinen
 
Joar, oder automatische Übersetzer, die z.B. ein "%s" trennen.
In "% s" oder die beiden wild verteilen, bzw. Teile weglassen.

Hatte mal mit Poedit gespielt und dort eine automatische Google-Translate-Übersetzung reingeladen.
Da kamen die wildesten Ergebnisse bei raus.

Oder bei einigen Online-Spielen gibt es z.B. im Chat/Mails eine automatische Üersetzung, wo bei Systemnachrichten die Platzhalter gern mal zerstört werden.

dummzeuch 7. Feb 2020 15:30

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von himitsu (Beitrag 1456931)
Texte mit Formatierungen aus anderen Quellen sind immer nett, wenn das Programm plötzlich verreckt.
(Übersetzung/Datenbank wo Texte durch user bearbeitet oder über eine Synchronisierung/Update nachgeladen werden)

Drum hab ich bei uns das Format überschrieben/überdeckt.
Der Code muß nur in eine Unit die immer nach den SysUtils eingebunden wird.

Wenigstens "etwas" anzeigen und das Programm nicht abkratzen lassen.

Wir gehen bei unseren Programmen noch einen Schritt weiter und installieren einen Hook für die Format-Funktion. Das passiert in einer Unit, die automatisch in allen unseren Programmen eingebunden wir. Dann wird sowas auch für fremden Code abgefangen. Und man kann man muss auch nicht daran denken, überall eine solche Unit einzubinden.

Am meisten nervt mich aber, dass man den Datentyp überhaupt angeben muss. Write kann den ja auch automatisch erkennen, warum gibt es bei Format nicht sowas wie einen generischen Platzhalter:

Delphi-Quellcode:
Format('Der Wert ist %g', [IrgendeineVariable]);


Die Format-Funktion weiss ja, welcher Datentyp übergeben wurde, denn eigentlich ist das ja ein Variant mit entsprechenden Informationen. Den kann man dann halt nach String konvertieren. Für viele Anwendungen würde das ausreichen.

Aber das Thema war ja ein anderes ...

Luckie 7. Feb 2020 15:44

AW: Variablen in Stringliteral inlinen
 
Und woher soll write wissen, wie viele Nachkommastellen du willst? Wie viele führende Nullen?

Poelser 7. Feb 2020 16:07

AbarW: Variablen in Stringliteral inlinen
 
Moin,

da wäre so etwas wie die Systemeinstellungen für das Datumsformat denkbar. Wenn der Entwickler das anders haben will, dann könnte er die Formatanweisungen wie bisher benutzen.

Bis denne,
Edmund

Stevie 7. Feb 2020 16:39

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von dummzeuch (Beitrag 1456938)
Die Format-Funktion weiss ja, welcher Datentyp übergeben wurde, denn eigentlich ist das ja ein Variant mit entsprechenden Informationen.

Falsch! Es ist ein TVarRec - und die haben ebend nicht genügend Informationen über den Typen.

Hab erst gestern geschaut, ob man Format so umbauen könnte wie string.Format in .NET, die dort übergebenen Parameter sind alle object und haben somit die exakten Typeninformationen dabei.
Mit SysUtils.Format kann ich nichtmal Datum oder Zeit allein über den Formatstring ausgeben :kotz:

Zitat:

Zitat von Luckie (Beitrag 1456939)
Und woher soll write wissen, wie viele Nachkommastellen du willst? Wie viele führende Nullen?

Indem man es angibt - das erfordert aber nicht die grundsätzliche Angabe des Typens - siehe string.Format

Übrigens solltet ihr nicht Write und Format verwechseln, die funktionieren unterschiedlich.

Luckie 7. Feb 2020 17:20

AW: Variablen in Stringliteral inlinen
 
Ich meine natürlich Format. Sorry.

himitsu 7. Feb 2020 18:16

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von dummzeuch (Beitrag 1456938)
Wir gehen bei unseren Programmen noch einen Schritt weiter und installieren einen Hook für die Format-Funktion.

Wir arbeiten viel mit Packages und DLLs.
Eine große Hook-Engine wollte/konnte ich für die paar Kleinigkeiten nicht so einfach integrieren. (die das dann je nach Ziel richtig erledigt)
Und beim selbst hooken (JMP+Adresse in Prozeduranfang schreiben oder bei Packages/DLL in "allen" Libraries die Referenz überschreiben) muß man da bissl aufpassen, dass man den hook nicht nur im aktuellen Package/DLL macht (war mir einmal passiert (vorsicht vor Copy&Paste aus Hook-Tutorials, denn die sind fast immer nur für Ein-EXE-Anwendungen) und ob man dann die originale Funktion auch noch verwenden möchte und demnach eben nicht den Prozeduranfang überschreiben kann.

TurboMagic 7. Feb 2020 18:24

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1456825)
Nun Ich generiere delphi code für eine include datei...jetzt mit format('Bla%d blabla%s '[x,y]) :(
Glaube mir die Ausgabe mit string interpolation hätte den Quellcode in den strings sicher leichter manipulierbar und umstellbar gemacht.
Ich sage ja nicht das es der Heilige Gral ist, frei von jedwedem Nachteil.

Dennoch hätte Stringinterpolation mir bei der Aufgabe echt was gebracht(leichte Umstellbarkeit des Codes in den Strings)
Das andere Übel ist die häßliche art und weise wie Einzelhochkomma escaped werden....
Sowohl QuotedString('TADA') als auch ''''''''''''''''''' sind keine sehr befriedigende Art sowas zu machen.
Auch ein Multiline String literal wäre schon schön für diese Aufgabe gewesen.

Schon mal was davon gehört, dass du deinen Platzhaltern in den Formatstrings Indexe verpassen kannst?

Format('Mein Name ist %0:s und ich stamme aus %1:s', ['Max', 'Musterhausen']);
Format('Ich stamme aus %1:s und mein Name ist %0:s', ['Max', 'Musterhausen']);

Grüße

TurboMagic

TurboMagic 7. Feb 2020 18:28

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Stevie (Beitrag 1456944)
Übrigens solltet ihr nicht Write und Format verwechseln, die funktionieren unterschiedlich.

Jaaa...
Write nutzt Compiler Magic.
Das war zu Turbo Pascal Zeiten eine der häufigsten Fragen in den Newsgroups:
"Wie kann ich eine Funktion oder Prozedure schreiben die wie Write eine variable ANzahl Parameter übergeben bekommt?"

Antwort:
"Geht nicht. Write ist Compiler Magic" ;-)

Grüße

TurboMagic

himitsu 7. Feb 2020 18:31

AW: Variablen in Stringliteral inlinen
 
Jo, leider nicht genug Infos, aber mehr, als man bei sowas wie printf rein bekommt (dort garkeine Typ-Info, außer dem Wert oder einen Zeiger auf die Variable) und noch nichtmal die Anzahl der Parameter ist bekannt.

Hatte mal versucht ein Format zu basteln, wo die Daten wie bei printf übergeben werden.

In Delphi kann man sowas leider auch nicht nativ schreiben, aber jedenfalls man eine Funktion ohne die Parameter schreiben, die als Export deklarieren und in der selben Datei wieder einen Import auf sich selber, der dann in der Definition diese offenen Parameter hat.
Aber leider bekommt man eben keinerlei Infos die übergebenen Werte.
Darum muß man dort auch selber im String das "genaue" Format angeben (nicht nur %d sondern auch ob Byte, Word, LongWord, ShortInt, SmallInt, LongInt usw.)

Also in der Hinsicht ist Format doch recht einfach, auch wenn teilweise echt blöd ist.
Ich kann nicht %p nehmen und dann ein Objekt oder Integer reingeben, der in der aktuellen Pointergröße (32 oder 64) ausgegeben wird.
Oder einen Integer mit Tausenderpunkten, den muß man erst in einen Fließkomma umwandeln (x/1) und kann dann %.0n verwenden. (k.A. warum man nicht direkt einen Integer als Float darstellen darf usw.)


Zitat:

Wie kann ich eine Funktion oder Prozedure schreiben die wie Write eine variable ANzahl Parameter übergeben bekommt
Wie gesagt, man kann soeine Funktion schreiben (besser in eine DLL legen, denn innerhalb einer EXE schreiben und benutzen ist ein grauß), aber die Funktion weiß nicht was ihr übergeben wurde und das müsste man dann zusätzlich noch als Info mit reingeben.

Über die RTTI kann man ansonsten nur noch nativ "beliebige" Funktionen aufrufen. (siehe Invoke in System.RTTI.pas)

Dennis07 9. Feb 2020 21:35

AW: Variablen in Stringliteral inlinen
 
Oder man nimmt offene variante Array-Parameter:

Delphi-Quellcode:
procedure WriteValues(Values: array of const);
begin
  Write(String.Join(String.Empty, Values));
end;

WriteValues(['hallo', 123]);

QuickAndDirty 10. Feb 2020 11:46

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von TurboMagic (Beitrag 1456953)
Schon mal was davon gehört, dass du deinen Platzhaltern in den Formatstrings Indexe verpassen kannst?
Format('Mein Name ist %0:s und ich stamme aus %1:s', ['Max', 'Musterhausen']);
Format('Ich stamme aus %1:s und mein Name ist %0:s', ['Max', 'Musterhausen']);

Nein, bisher nicht. OK das ist schon mal ne gute Sache, ein bisschen TurboMagic quasi!
Ich denke ich werde das in meine Arbeitsweise aufnehmen.

Uwe Raabe 10. Feb 2020 12:07

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von TurboMagic (Beitrag 1456953)
Schon mal was davon gehört, dass du deinen Platzhaltern in den Formatstrings Indexe verpassen kannst?

#23

dummzeuch 10. Feb 2020 13:10

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Luckie (Beitrag 1456939)
Und woher soll write wissen, wie viele Nachkommastellen du willst? Wie viele führende Nullen?

Wenn man das explizit braucht, verwendet man halt %f statt %g. Und ansonsten funktionert %g bei Floats halt wie %f, auch da nimmt Format ja defaults.

dummzeuch 10. Feb 2020 13:13

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von Stevie (Beitrag 1456944)
Zitat:

Zitat von dummzeuch (Beitrag 1456938)
Die Format-Funktion weiss ja, welcher Datentyp übergeben wurde, denn eigentlich ist das ja ein Variant mit entsprechenden Informationen.

Falsch! Es ist ein TVarRec - und die haben ebend nicht genügend Informationen über den Typen.

Doch, zumindest zu den Variablen, die Format standardmäßig unterstützt. Bei anderen hat man sowieso ein Problem.

Stevie 10. Feb 2020 23:13

AW: Variablen in Stringliteral inlinen
 
Zitat:

Zitat von dummzeuch (Beitrag 1457048)
Doch, zumindest zu den Variablen, die Format standardmäßig unterstützt. Bei anderen hat man sowieso ein Problem.

TVarRec kennt nur 32 und 64bit Integer mit Vorzeichen und kennt kein TDateTime - Float nur als Extended oder Currency (da wär ja sogar Variant besser -.-)

himitsu 11. Feb 2020 10:38

AW: Variablen in Stringliteral inlinen
 
Und Variant kann man sogar nativ um neue Typen erweitern. (Delphi hat z.B. seine AnsiString und UnicodeString dort reingepackt)


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 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