Wieso ist property nicht änderbar ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

theo hat geschrieben:
Do 24. Sep 2020, 10:59

Vielleicht ist der Record aber auch schlicht nicht der ideale Datentyp für einen Property Setter.
Hi!

Indeed.
Alle visuellen Komponenten haben left,top,width,height.

Die kann man einzeln setzen.
Oder mit setBounds bzw. setSize mehrere auf einmal.

Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hi!

Ich denk immer noch zu altmodisch.

Trect kann das doch alles inzwischen:

Code: Alles auswählen

TRect = packed
  record
  ......
public
       property Height: Longint read getHeight write setHeight;
       property Width : Longint read getWidth  write setWidth;
       property Size  : TSize   read getSize   write setSize;
       property Location  : TPoint read getLocation write setLocation;
       case Longint of
         0: (Left,Top,Right,Bottom : Longint);
         1: (TopLeft,BottomRight : TPoint);
         2: (Vector:TArray4IntegerType);
       end;              
end;
Winni

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

Re: Wieso ist property nicht änderbar ?

Beitrag von fliegermichl »

Hi,

nichtsdestotrotz kannst du auf Einzelbestandteile einer property vom Typ TRect nicht schreibend zugreifen.
Beispiel:

Code: Alles auswählen

type
 TMyDingen = class
 private
  fFrameSize : integer;
  fSize : TRect;
  function GetInnerframe : TRect;
  function SetInnerframe(const Value : Trect);
 public
  property Innerframe : TRect read GetInnerframe write SetInnerframe;
 end;
 
 function TMyDingen.GetInnerframe : TRect;
 begin
  with Result do
  begin
   Left := fSize.Left + fFrameSize;
   Top := fSize.Top + fFrameSize;
   Right := fSize.Right - fFrameSize;
   Bottom := fSize.Bottom - fFrameSize;
  end;
 end;
 
 procedure TMyDingen.SetInnerframe(const Value : TRect);
 begin
  with Value do
  begin
   fSize.Left := Left - fFrameSize;
   fSize.Top := Top - fFrameSize;
   fSize.Right := Right + fFrameSize;
   fSize.Bottom := Bottom + fFrameSize;
  end;
 end;
 
Wo ist hier die Adresse von Innerframe?

PascalDragon
Beiträge: 830
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: Wieso ist property nicht änderbar ?

Beitrag von PascalDragon »

Winni hat geschrieben:
Do 24. Sep 2020, 10:49
Funktioniert wunderbar:
Du hast nicht richt richtig gelesen:

Code: Alles auswählen

program tproptest;

{$mode objfpc}{$H+}

uses
  Types;

type
  TTest = class
  private
    FRect: TRect;
    function GetRect: TRect;
  public
    property Rect1: TRect read GetRect;
    property Rect2: TRect read FRect;
  end;

function TTest.GetRect: TRect;
begin
  Result := FRect;
end;

var
  t: TTest;
  p: PLongInt;
begin
  t := TTest.Create;
  try
    p := @t.Rect1; // Error: Variable identifier expected
    p := @t.Rect2; // ok
  finally
    t.Free;
  end;
end.
FPC Compiler Entwickler

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Wieso ist property nicht änderbar ?

Beitrag von Warf »

Man kann das folgende machen:

Code: Alles auswählen

procedure Foo;
type
  PRect = ^TRect;
begin
  PRect(@SomeObj.Rect)^.Top := 42;
end;
Das gesagt. das funktioniert nur (wie PascalDragon schon erwähnt hat) wenn die property direkt ein Feld referenziert. Außerdem, wenn die property einen setter hat, kompiliert das zwar, ist aber letztendlich kaputter code, weil der setter umgangen wird (und damit potentiell error checking, seiteneffekte, etc).

Beispiel:

Code: Alles auswählen

TTest = class
  FInternalMemory: Array of Array of Byte;
  FSize: TPoint;
  procedure SetSize(const AValue: TPoint);
...
  property Size: TPoint read FSize write SetSize;
...

procedure TTest.SetSize(const AValue: TPoint);
begin
  SetLength(FInternalMemory, AValue.X, AValue.Y);
  FSize := AValue;
end;
Wenn man hier jetzt via pointern FSize ändert, würde die interne memory nicht gereallocated werden, und man wäre in einem kaputten state der über kurz oder lang wahrscheinlich in einer segfault endet. Damit lassen sich übringens auch read only properties beschreiben.

Also auch wenn es möglich ist solche schweinereien über pointer zu machen, wäre ich da ganz ganz vorsichtig. Wenn ein setter dahinter steht, oder schlimmer noch, die property read only ist, dann macht man definitiv etwas das die komponente eigentlich nicht erlauben will

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

Re: Wieso ist property nicht änderbar ?

Beitrag von theo »

@Warf: Das wurde hier eigentlich schon gesagt
Die eigentliche Frage lautet. "Wie hältst du es mir den Regeln der OOP"?
Wenn man versucht, die OOP auszutricksen wie Winni, kann man es auch gleich sein lassen und C oder ASM schreiben.
Erinnert mich irgendwie an den Arduino Thread. :wink:

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

Re: Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Ich habe das Problem umgangen, in dem ich auch TRect verzichtete.
Ich habe nun 4 property Left, Width, etc.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Wieso ist property nicht änderbar ?

Beitrag von Warf »

theo hat geschrieben:
Do 24. Sep 2020, 17:22
Wenn man versucht, die OOP auszutricksen wie Winni, kann man es auch gleich sein lassen und C oder ASM schreiben.
Erinnert mich irgendwie an den Arduino Thread. :wink:
Winni hat ja nicht mal wirklich OOP ausgetrickst. Das man die addresse von Properties holen kann ist ein Feature. Das ist zwar natürlich kaputtes design, aber dank delphi kompatibilität ist kaputtes design auch ein feature im FPC.
Das wirklich kaputte was Winni macht ist das er der meinung ist er kennt die interne representation des records besser als der Compiler. Wie in meinem beispiel gezeigt ist den kompiler zu fragen das er von einem pointer auf einen record auf ein element zu zu greifen, eine zeile ist. Winni's code ist komplizierter, und muss annahmen über die interne represenation treffen. Das ist schlechtes programm design, aber hat nix mit OOP zu tun, den records und pointer gibts bereits schon deutlich länger als OOP, und solchen code würde man z.b. auch nicht in C schreiben. Tatsächlich muss ich hier mal C verteidigen, denn das ganze ist in C sogar auch nicht erlaubt, da es undefiniertes verhalten ist. Das casten von pointer typen nicht definiert ist (außer von typisiertem pointer nach void* und anders rum), in diesem fall ist also das casten von einem record pointer auf einen integer pointer undefiniertes verhalten und wäre damit kein valider C code.

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

Re: Wieso ist property nicht änderbar ?

Beitrag von theo »

Warf hat geschrieben:
Fr 25. Sep 2020, 17:10
Winni hat ja nicht mal wirklich OOP ausgetrickst.
Du hast natürlich recht, dass hier auch Ungereimtheiten auf tieferer Ebene vorliegen.
Dennoch wurde hier primär versucht, den Property Setter zu "umschiffen".
Meiner Meinung nach findet OOP hauptsächlich im Kopf des Programmierers statt.
Inwieweit der Compiler/Interpreter OOP erzwingen sollte, darüber kann man streiten.
Wer keinen Bock auf OOP hat, der muss ja nicht, aber dann soll er auch konsequent sein und sie nicht versuchen zu hintergehen.

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

Re: Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Ohne OOP geht es heutzutage kaum mehr. Ausser bem Embeded Systemen und Kondolenanwendungen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hej!

Ich wollte hier keine Generaldebatte anzetteln.

Die Situation war eigentlich trivial:

Ein StringGrid. Beim Programmstart sortiere ich schon mal die erste Spalte.
Davon bekommt die property SortColumn aber nix mit, sie steht immer noch auf -1,
weil sie nur auf UserClicks reagiert: Designfehler.

Realität und SortColumn widersprechen sich jetzt.
SortColumn ist außerdem readony.
Nun wollte ich - um den User nicht zu verwirren - den Sotierstatus darstellen.
Sonst ist erst beim zweiten Mausklick auf den Header zwecks Sotierens
wieder alles korrekt.

Da stand ich nun und die property gab mir keine Chance zum Eingreifen.
Dazu hätte ich erstmal ne aufgebohrte Tochterklasse bauen müssen.
Viel zu viel Action für das Problem!

C'est la.

Winni

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Wieso ist property nicht änderbar ?

Beitrag von Timm Thaler »

Mathias hat geschrieben:
Fr 25. Sep 2020, 18:30
Ohne OOP geht es heutzutage kaum mehr. Ausser bem Embeded Systemen und Kondolenanwendungen.
Dazu hätte ich gern mal eine Definition, wo OOP anfängt. Bei manchen ist OOP ja schon, wenn man paar Variablen in ein Record packt und das weiterreicht. Bei anderen darf kein Programmablauf mehr erkennbar sein.

Ich tu mich da immer schwer zu sagen, das ist jetzt hier OOP.

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

Re: Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Ein Record ist definitiv keine OOP, genau so wenig wie ein type helper.
OOP muss Vererbungen enthalte, sowie überschreibare Methoden.
Ein sehr gutes Beispiel für OOP ist FreeVision.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wieso ist property nicht änderbar ?

Beitrag von Winni »

Hi!

Records waren schon in N. Wirths erster Version von Pascal vorhanden also ~ 1970.
Haben dann viele Sprachen abgekupfert und - damit es nicht so peinlich ist - gleich anders
genannt.

Über Objectorientierung dachten zu dem Zeitpunkt nur die "Verrückten" von Simula und Smalltalk nach.
Die OOP wurde erst Ende der 80er bis Anfang der 90er Mode. 1987 kam Oberon. 1995 kam Delphi.

Nur um das mal zeitlich einzuordnen.

Winni

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

Re: Wieso ist property nicht änderbar ?

Beitrag von Mathias »

Turbo Pascal hast du noch vergessen. Das kannte auch schon Objekte.
Zuletzt geändert von Mathias am Sa 26. Sep 2020, 07:49, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten