Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi PosExUltra - Ultimative Stringsuche/Parser (https://www.delphipraxis.net/148055-posexultra-ultimative-stringsuche-parser.html)

GPRSNerd 26. Feb 2010 09:27

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Erzeugt und wieder freigegeben habe ich die Stringlist natürlich ausserhalb, eine Property ist diese ja auch nicht:

Delphi-Quellcode:
  slSplitString:=TStringList.Create;
  try
    slSplitString:=ExtractBetween(dummy, 'http://', '.de', '', '', true);
    Memo.Lines.AddStrings(slSplitString);
  finally
    slSplitString.Free;
  end;

DeddyH 26. Feb 2010 09:29

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Und damit hast Du Dir die Referenz der erzeugten Liste mit einer nichtexistenten überschrieben. Mach es doch wie vorgeschlagen: übergib die Liste als (const-)Parameter und alles wird gut :)

[edit] Da waren mir zu viele "und"s drin :mrgreen: [/edit]

GPRSNerd 26. Feb 2010 10:07

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Hab ich schon längst wieder gemacht. :)
Es ging mir nur darum, zu verstehen, was hier schief läuft.

Danke für die Infos und die Geduld.

xZise 26. Feb 2010 10:21

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Hast du es schon bereits verstanden? :D

Ansonsten eine kleine Erklärung:
Du gibst mit der Funktion via Result etwas zurück. Das macht auch deine Zuweisung deutlich. Wenn man schreibt a := b dann schreibt man quasi den Inhalt von b in a. Das Problem dabei ist, das du nirgends der Funktion sagst, wie denn das erstellte Objekt lautet, dass zurückgegeben wird. Ich mach mal ein Beispiel:
Delphi-Quellcode:
function answer : Integer;
begin
  Result := 42 * Result;
end;

var
  a : Integer;
begin
  a := 10;
  a := answer;
  ShowMessage(IntToStr(a));
end;
Das ist quasi dein Beispiel: Du initialisierst a und schreibst dann den Wert der Funktion rein, und versuchst a in der Funktion zu benutzen. Wahrscheinlich steht nachher im Dialog 0, weil Result normalerweise mit 0 initalisiert wird. Wenn man das jetzt etwas umschreibt und die Funktion umgeht sieht das dann so aus (woraus klar werden dürfte, warum das nicht geht):
Delphi-Quellcode:
var
  a, b : Integer;
begin
  a := 10;

  // Code von answer
  b := 42 * b;

  a := b;
  ShowMessage(IntToStr(a));
end;
Das heißt, Result ist wie eine lokale Variable und nur in der Funktion sichtbar, womit es nicht den Wert von a hat.
Ich hoffe das ist soweit verständlich.

MfG
Fabian

PS: Es kann auch sein, dass a ≠ 0 ist, weil man nicht sicher sein kann, mit was Result oder b initalisiert werden. In der Regel wird a aber 0 sein ;)

GPRSNerd 26. Feb 2010 10:31

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Jetzt hats Klick gemacht, danke.
Schon witzig, wenn einem so ein Grundlagenproblem nach vielen Jahren Programmiertätigkeit noch nicht untergekommen ist.

DeddyH 26. Feb 2010 10:34

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Um das noch weiter auszuführen: TStrings ist ja eine Klasse. Will man nun ein Objekt dieser Klasse in einer Funktion zurückgeben, muss sie auch innerhalb der Klasse Funktion instanziert werden. Da aber die Freigabe nicht innerhalb des Blocks (also der Funktion) erfolgen kann, in dem sie instanziert wurde (der Rückgabewert wäre ja sonst hinfällig), muss man sehr genau aufpassen, dass man sich kein Speicherleck einfängt. Aus genau diesem Grund gilt diese Vorgehensweise als unschön. Der einzige mir bekannte sinnvolle Einsatzzweck einer Funktion, die ein Objekt zurückgibt, ist der Getter einer Property. Es mag evtl. noch weitere geben, aber es fallen mir spontan keine ein. Zur angesprochenen Property aber noch schnell ein Beispiel:
Delphi-Quellcode:
type
  TMyClass = class
  private
    //privates Feld vom Typ der Klasse (initial nil)
    FStrings: TStrings;
    //Getter-Methode
    function GetStrings: TStrings;
  public
    //Property
    property Strings: TStrings read GetStrings;
  end;

...

function TMyClass.GetStrings: TStrings;
begin
  if not Assigned(FStrings) then
    FStrings := TStringlist.Create;
  Result := FStrings;
end;
Der Sinn einer solchen Vorgehensweise liegt darin, Objekte erst dann zu erzeugen, wenn diese auch wirklich gebraucht werden, im obigen Beispiel also beim ersten Zugriff auf die Property.

[edit] Blödsinn korrigiert (s.o.) [/edit]

Blup 26. Feb 2010 16:41

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Zitat:

Zitat von DeddyH
Und damit hast Du Dir die Referenz der erzeugten Liste mit einer nichtexistenten überschrieben. Mach es doch wie vorgeschlagen: übergib die Liste als (const-)Parameter und alles wird gut :)

[edit] Da waren mir zu viele "und"s drin :mrgreen: [/edit]

Die Liste als const-Parameter zu übergeben ist fast genauso falsch wie als var-Parameter.
In beiden Fällen wird eine Referenz auf eine Objektvariable erwarted, damit ist die direkte Übergabe von TStrings-Property nicht möglich.

Vor Parametern für einfache Datentypen ohne Referezzählung braucht auch kein const zu stehen.
Ein Boolean nimmt auf dem Stapel ebenso viel Speicher ein, wie ein Zeiger auf eine Boolean-Variable/Konstante.
Innerhalb der Prozedur kann einfacher auf den Wert zugegriffen werden, als diesen bei jedem Zugriff über den Zeiger zu lesen/schreiben.

Mein Vorschlag:
Delphi-Quellcode:
procedure ExtractBetween(const aSource, aPrefix, aSuffix, aNewPrefix, aNewSuffix : string;
                         aWords : TStrings;
                         aFindAll : Boolean = True);

DeddyH 26. Feb 2010 16:46

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Zitat:

Zitat von Blup
..., damit ist die direkte Übergabe von TStrings-Property nicht möglich.

Delphi-Quellcode:
procedure FillWithNumbers(const aList: TStrings);
var i: integer;
begin
  aList.Clear;
  for i := 0 to 100 do
    aList.Add(Format('%d',[i]));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FillWithNumbers(Memo1.Lines);
end;
Komischerweise funktioniert das bei mir, obwohl ich das wohl schon seit Jahren falsch mache.

xZise 26. Feb 2010 18:54

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Ich vermute, er verwechselt das mit var was natürlich nicht geht ;)

MfG
Fabian

Blup 1. Mär 2010 12:18

Re: PosExUltra - Ultimative Stringsuche/Parser
 
Ich habe mich zu kurz und damit falsch ausgedrückt :oops:
Zitat:

Zitat von Blup
Die Liste als const-Parameter zu übergeben ist fast genauso falsch wie als var-Parameter.

Ich hätte schreiben sollen "Die Übergabe als const-Parameter ist überflüssig".
Zitat:

Zitat von Blup
In beiden Fällen wird eine Referenz auf eine Objektvariable erwarted,

Tatsächlich behandelt der Compiler "const" nur, in dem er Zuweisungen auf die Variable innerhalb der Prozedur verbietet und entsprechend auch die Weitergabe als var-Parameter an weitere Funktionsaufrufe. Der erzeugte Code ist identisch, ob "const" angegeben wird oder auch nicht.
Zitat:

Zitat von Blup
damit ist die direkte Übergabe von TStrings-Property nicht möglich.

Der Teilsatz bezieht sich natürlich auf var-Parameter. Als weitere Einschränkung muss die Variable auch genau dem Typ entsprechen. Wird die Variable z.B. als TStringList deklariert, ist eine direkte Übergabe unzulässig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:50 Uhr.
Seite 4 von 5   « Erste     234 5      

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