my issue is pretty simple. I have a dwsUnit which have this code:
type
TPointCoord = record
X: Float;
Y: Float;
Z: Float;
end;
type
TMyClass = class
private
fPosition: TPointCoord;
function GetPosition: TPointCoord;
procedure SetPosition(Val: TPointCoord);
public
property Position: TPointCoord read GetPosition write SetPosition;
constructor Create;
end;
function TMyClass.GetPosition: TPointCoord;
begin
Result := fPosition;
end;
procedure TMyClass.SetPosition(Val: TPointCoord);
begin
fPosition := Val;
end;
constructor TMyClass.Create;
begin
inherited Create;
fPosition.X := 1;
fPosition.Y := 2;
fPosition.Z := 3;
end;
var
mc: TMyClass;
begin
mc := TMyClass.Create;
mc.Position.X := 2; //Syntax Error
end.
At mc.Position.X (or Position.Y or Z) i get:
Syntax Error: Cannot assign a value to the left-side argument [line: 42, column: 17]
What is the meaning of this? Is Record read-only if is a property? And how I can access that from Delphi Side. (the second issue, not a really big deal)
The reason for this error is because you're using a property of type record.
Record type is a value type, which means it's copied on assignment rather than referenced (like a class), so a function (or property) returning a record will make a copy and return a different record.
So your line
mc.Position.X := 2
is effectively equivalent to
temp := mc.getPosition;
temp.X := 2;
with "temp" being a different variable/storage from fPosition, so that code wouldn't change fPosition.X, it would only the "hidden" temporary copy's X field.
As this is generally unlikely to be what you're after, the DWS compiler, just like Delphi, throws an error.
The typical solution is to offer a distinct PositionX property, which will provide access to the X field of fPosition like
property PositionX : TPointCoord read (FPosition.X) write (FPosition.X);
or you can use explicit getters/setters, if you need more than the X field assigned.
Another solution would be use a reference types (a class f.i.), though this may not be very practical for a position or coordinate.