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

_______________________________________________
fpc-devel maillist  -  [email protected]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to