Why can I have a local variable in a method that out-scopes a class property without a hint or warning?

Why can I have a local variable in a method that out-scopes a class property without a hint or warning?

One thing is allowing name overlaps for method parameters, but for local variables – does that even make sense?

type

  TBadClass = class

  private

    FValue: Integer;

    procedure SetValue(const Value: Integer);

  public

    procedure CheckValue;

    property Value: Integer read FValue write SetValue;

  end;

procedure TBadClass.SetValue(const Value: Integer);

begin

  FValue := Value;

end;

procedure TBadClass.CheckValue;

var

  Value: Integer;

begin

  Value := 1;

  Writeln(‘Value ‘, Value);

  Writeln(‘Self ‘, Self.Value);

  Self.Value := 2;

  Writeln(‘Value ‘, Value);

  Writeln(‘Self ‘, Self.Value);

end;

Output is

Value 1

Self 0

Value 1

Self 2

 

14 thoughts on “Why can I have a local variable in a method that out-scopes a class property without a hint or warning?


  1. I think this has been how the language behaves (and most other languages do). I know this is very odd, but technically you can access both, as your code shows. Same for a parameter matching a field.


    What if you have some perfectly working code and you add a field? What if the field is added to a base class? Too many scenarios, I think, some of which could have merit…


  2. This is how Delphi scope rules work. Inner block declarations always take precedence over outer block. 


    Adding warnings to that kind of behaviour would very likely result in having warnings all over your code.


  3. I think that is one of the things that some metric tools like Pascal Analyzer can spot (not sure about the metrics that are included in higher versions of Delphi though)


    P.S. FWIW thats an instance property and not a class property


  4. A hint would make sense in many cases TBH.


    Yes, it would be annoying in the scenario described by Marco Cantù but on the other hand if you keep adding fields or methods with names overlapping local ones, you will eventually end up with a big ball of hard to maintain code.


  5. Eric Grange Yes, some hints the compiler could generate would be useful for sure. I think it goes into the same direction of the reintroduce keyword where you tell the compiler “YES, I know what I am doing and that I am hiding a virtual method!”


  6. I’d certainly like an option that would warn me of namespace pollution for local variables and withs, possibly also for unit scope clashes – with the option of turning it off per unit with a compiler directive.


  7. Asbjørn Heid I would like to have the language “case-exclusive” personally ie. you declare “Something” then you have to use “Something” everywhere, and can’t declare “something” alongside, ie. no C/Java-like horror “Class class;”

Leave a Reply