[fpc-devel] [] property overloads
Ondrej Pokorny
lazarus at kluug.net
Mon Jul 1 22:15:48 CEST 2019
On 01.07.2019 21:04, Michael Van Canneyt wrote:
> On Mon, 1 Jul 2019, Ondrej Pokorny wrote:
>> If the compiler encounters "Mytest.StringArray" it can be evaluated
>> only as the non-indexed overload.
>
> Well... We can of course discuss forever, and still not agree.
> I suggest we let the compiler people have the last word on this. They
> know best. And if you turn out to be right: so much the better.
Just an info: the non-indexed/indexed property overload resolving is
currently supported in FPC:
https://bugs.freepascal.org/file_download.php?file_id=23296&type=bug
(File arraypropenum.lpr in https://bugs.freepascal.org/view.php?id=28820 )
Yes, currently it's a bug because the overloads are taken from the
methods and not from property definitions. But if the overloads were
taken from property definitions, it would be a valid feature, IMO. (The
bug in FPC is that indexed property information is not stored in the PPU
- only the link "property name"->"getter name"+"setter name" is stored
and therefore the information about the valid property definition is
lost. The parameters and results are consequently taken from the
getter/setter. I.e., the compiler can cope with the non-indexed/indexed
property overloads since the very beginning.
This bug allows you to have some serious fun. For example this syntax is
allowed (!!!):
c := TMyClass.Create;
Writeln(c[]); // c[] returns a Double
c[] := 'oh my lord'; // c[] accepts a string
A compilable example:
program Project1;
{$mode objfpc}
type
TValue = record A: Integer end;
TMyClass = class
private
function GetValue: Double; //
result := x[]; syntax (without an index)
function GetValue(index: integer): TValue; //
result := x[999];
function GetValue(index: string): string; //
result := x['abc'];
procedure SetValue(aindex: integer; const aValue: Double); //
x[999] := 9.9;
procedure SetValue(aindex: integer; const aValue: TValue); //
x[999] := MyValue;
procedure SetValue(aindex: string; const aValue: string); //
x['abc'] := 'xyz';
procedure SetValue(const aValue: string); // x[]
:= 'oh god'; syntax (without an index)
public
property Index[aindex: integer]: TValue read GetValue write
SetValue; default;
end;
{ TMyClass }
function TMyClass.GetValue(index: integer): TValue;
begin
Result.A := index;
end;
function TMyClass.GetValue(index: string): string;
begin
Result := index+index;
end;
function TMyClass.GetValue: Double;
begin
Result := Pi;
end;
procedure TMyClass.SetValue(aindex: integer; const aValue: Double);
begin
Writeln(aindex, ' ', aValue);
end;
procedure TMyClass.SetValue(aindex: integer; const aValue: TValue);
begin
Writeln(aindex, ' ', aValue.A);
end;
procedure TMyClass.SetValue(const aValue: string);
begin
Writeln(aValue);
end;
procedure TMyClass.SetValue(aindex: string; const aValue: string);
begin
Writeln(aindex, ' ', aValue);
end;
var
c: TMyClass;
begin
c := TMyClass.Create;
Writeln('Pi: ', c[]);
Writeln(c[999].A);
Writeln(c['key']);
c['key'] := 'hello';
c[] := 'oh my lord';
c.Index := 'property fun';
ReadLn;
end.
Ondrej
More information about the fpc-devel
mailing list