Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-03

Code completion: Error: ancestor has same name as class.

7 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marcos Douglas

The program below compiles. But if I try to use code completion here writeln(s.F...
Occurs this error:
test.lpr(8,31) Error: ancestor has same name as class.

program test;
{$mode objfpc}{$H+}
uses SysUtils, Classes;
type
  TStringList = class(Classes.TStringList)
  public
    function Foo: string;
  end;
function TStringList.Foo: string;
begin
  result := 'Foo';
end;
var
  s: TStringList;
begin
  s := TStringList.Create;
  writeln(s.Foo);
  s.Free;
  readln;
end.

Marcos Douglas

Reply by email

Marcos Douglas
to Marcos Douglas
Marcos Douglas wrote 30 lines
The program below compiles. But if I try to use code completion here writeln(s.F... Occurs this error: test.lpr(8,31) Error: ancestor has same name as class. program test; {$mode objfpc}{$H+} uses SysUtils, Classes; type ?TStringList = class(Classes.TStringList) ?public ? ?function Foo: string; ?end; function TStringList.Foo: string; begin ?result := 'Foo'; end; var ?s: TStringList; begin ?s := TStringList.Create; ?writeln(s.Foo); ?s.Free; ?readln; end.
Like that:
type
  TMyStringList = Classes.TStringList;
  TStringList = class(TMyStringList)
  public
    function Foo: string;
  end;

...works fine.

Marcos Douglas

Reply by email

Mattias Gaertner
to Marcos Douglas: The program below compiles. But if I try to use code completion here writeln(s.F...…
Show quoted text 13 lines
The program below compiles. But if I try to use code completion here writeln(s.F... Occurs this error: test.lpr(8,31) Error: ancestor has same name as class. program test; {$mode objfpc}{$H+} uses SysUtils, Classes; type TStringList = class(Classes.TStringList)

The codetools have no circle detection when searching recursively. As a simple protection versus endless loops they do not support naming classes the same as their ancestort. And I agree with Juha, it is bad coding practice.

Mattias

Reply by email

Juha Manninen
to Marcos Douglas: The program below compiles. But if I try to use code completion here writeln(s.F...…

Marcos Douglas kirjoitti sunnuntai 06 maaliskuu 2011 03:57:02:

Show quoted text 5 lines
type TStringList = class(Classes.TStringList) public function Foo: string; end;

In any case your class name is very confusing. I would always use a different name. When someone else reads your code and sees TStringList he assumes it is a "normal" TStringList.

Juha

Reply by email

Marcos Douglas
to Mattias Gaertner: On Sat, 5 Mar 2011 22:57:02 -0300 The codetools have no circle detection when searching…
Juha Manninen wrote 10 lines
Marcos Douglas kirjoitti sunnuntai 06 maaliskuu 2011 03:57:02: > type > TStringList = class(Classes.TStringList) > public > function Foo: string; > end; In any case your class name is very confusing. I would always use a different name. When someone else reads your code and sees TStringList he assumes it is a "normal" TStringList.

It was just an example.
But there is an advantage, see below.

Mattias Gaertner wrote
The codetools have no circle detection when searching recursively. As a simple protection versus endless loops they do not support naming classes the same as their ancestort. And I agree with Juha, it is bad coding practice.

If you have a program with a lot of TEdit and you have to modify some feature (eg: when the Edit give the focus, your color will change) you can codify this new feature in your own unit (eg mystrctrls.pas) and you can put the new unit on uses clause (at the end or after on "real" unit of TEdit) and voial?! You have a "new" TEdit in runtime.

Nobody did that??

Marcos Douglas

Reply by email

leledumbo
to Marcos Douglas

Maybe for the programmer of the unit, but for the users, it's almost always a disadvantage. They will get unexpected behavior instead (especially if you put it along with other things in the unit where one might need some of them). Open LCL sources and see how its components are named. For your "advantage" case, I would give something like TColorEdit. Your proposal has an advantage of changing a component behavior just by changing the uses clause, that's also possible with the current situation. Example:

uses
  StdCtrls,ColorEdit;
type
  TEditCtrl = TEdit;

... // use TEditCtrl everywhere

when you want to change to TColorEdit, just change TEditCtrl definition to TColorEdit. Same type-savings as your proposal.

Reply by email

Marcos Douglas
to leledumbo
leledumbo wrote
Maybe for the programmer of the unit, but for the users, it's almost always a disadvantage. They will get unexpected behavior instead (especially if you put it along with other things in the unit where one might need some of them).

This "hack" is used in a company when I worked before. So, all programmer did know about it. Nobody got unexpected behavior.

Open LCL sources and see how its components are named.

There are no pattern in LCL sources. Some components have a prefix, some not...

Show quoted text 14 lines
For your "advantage" case, I would give something like TColorEdit. Your proposal has an advantage of changing a component behavior just by changing the uses clause, that's also possible with the current situation. Example: uses ?StdCtrls,ColorEdit; type ?TEditCtrl = TEdit; ... // use TEditCtrl everywhere when you want to change to TColorEdit, just change TEditCtrl definition to TColorEdit. Same type-savings as your proposal.

You din't TEdit class is already used in all sources. This hack provides a big change with a few lines code. This hack is used in programs that already exists. To new programs we use a new widget, of course (or not =).

Marcos Douglas

Reply by email