Scopes and names can really be deceiving.

Scopes and names can really be deceiving. A root class and a descendant class can both have public fields, properties and methods with the same name.

I really wonder why this doesn’t raise a warning or a even a hint?

(Berlin 10.1.x / Tokyo 10.2.x)

Output:

c: 1

TClass1:1

TClass1.PropTest:1

TClass2.Test:2

TClass2.PropTest:2

TClass1.Oops

Press any key:

Code:

program PublicScope;

{$APPTYPE CONSOLE}

{$R *.res}

uses

System.SysUtils;

type

TClass1 = class

public

Test: Integer;

constructor Create; virtual;

procedure Dump; virtual;

procedure Oops;

property PropTest:Integer read Test;

end;

TClass2 = class(TClass1)

public

Test:Integer;

constructor Create; override;

procedure Dump; override;

procedure Oops;

property PropTest:Integer read Test;

end;

{ TClass1 }

constructor TClass1.Create;

begin

Test := 1;

end;

procedure TClass1.Dump;

begin

Writeln(‘TClass1:’, Test);

Writeln(‘TClass1.PropTest:’, Test);

end;

procedure TClass1.Oops;

begin

Writeln(‘TClass1.Oops’);

end;

{ TClass2 }

constructor TClass2.Create;

begin

Inherited;

Test := 2;

end;

procedure TClass2.Dump;

begin

Inherited;

Writeln(‘TClass2.Test:’, Test);

Writeln(‘TClass2.PropTest:’, Test);

end;

procedure TClass2.Oops;

begin

Writeln(‘TClass2.Oops’);

end;

procedure Test;

var

c: TClass1;

begin

c := TClass2.Create;

try

Writeln(‘c: ‘, c.Test);

c.Dump;

c.Oops;

finally

c.Free;

end;

end;

begin

try

try

Test;

except

on E: Exception do

Writeln(E.ClassName, ‘: ‘, E.Message);

end;

finally

Write(‘Press any key: ‘);

Readln;

end;

end.

14 thoughts on “Scopes and names can really be deceiving.


  1. Because it was never implemented and the designers of the language never paid attention to its consistency. C# for example raises a warning telling you that a member is hiding an inherited member and you need to explicitly add the new keyword (similar to reintroduce for virtual methods in Delphi).


  2. Well, I’d want at least a hint, and perhaps a compiler switch to ignore such hints, for those that abuse the way it works today.


    I guess I should QP it.


  3. This is where static code analysis comes to the rescue. At least Pascal Expert and Pascal Analyzer (http://peganza.com/) do emit these hints (not sure about FixInsight here).


    Each time I hear claims that the IDE should do it in the first place, I am glad that it does not and thus opens a market for those kinds of external tools. If this market vanishes we will probably loose some really helpful tools and tool developers.


  4. Uwe Raabe The C# compiler does and there is still a market for VS extensions (see Resharper). So whats your point? That making a product that lacks basic features is good for third party eco system?


  5. Stefan Glienke Not literally, but sort of, yes – when removing the “basic”. The market for VS extensions may still be big enough to make some profit even if it is comparable small. That doesn’t hold true for Delphi. Note that I don’t want to bind this to the explicit issue shown above. It is more of a general statement. So I would not phrase it “lack of basic features”, but rather “containing the basics, but giving room for nice and useful things to 3rd parties”. Preferences may differ here and not everything useful for myself gets the same appreciation by others. Putting all things into the main product may reduce diversity in the end.


  6. The problem is that the standard answer to “IDE lacks feature xy” (and most of the time that’s not something fancy) is: “with (most of the time a commercial one) you can do that”


    And especially seasoned developers are very much subject to habit and “been doing it like that since…” that they don’t see how much better it could be.


    Also FWIW StyleCop runs circles around any static code analysis tool available for Delphi and is open source.


  7. David Heffernan – You can “inject” a replacement class or method, simply by adding the scope overshadowing unit in the uses clause. Handy for avoiding replacing a multitude of class type declarations or method references. I’ve typically used it for debugging scenarios.


    One example is using it for intercepting OutputDebugString to capture output to a log file system without having to replace a multitude of references.


  8. Lars Fosdal OK, but there are plenty of other ways to do that. And the other ways are generally more explicit. I certainly don’t think it’s worth all the downsides.

Leave a Reply