Recent

Author Topic: Error: Duplicate identifier XXX when method param has same name of variable  (Read 1287 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Is it possible to avoid "Error: Duplicate identifier "XXX"" in definition of method SetValue. I forces me to call the parameter somehow differently _field, field_, fieldValue, and I don't like so much.

Code: Pascal  [Select][+][-]
  1. unit ExampleUnit;
  2.  
  3. {$mode objfpc}
  4.  
  5. interface
  6.  
  7. type
  8.  
  9.   TExampleClass = class(TObject)
  10.   public
  11.     Field: string;
  12.     procedure SetValue(field: string);
  13.   end;
  14.  
  15. implementation
  16.  
  17. procedure TExampleClass.SetValue(field: string);
  18. begin
  19.   Self.Field := field;
  20. end;
  21.  
  22. end.
  23.  

BTW I note that it doesn't raise the same error if there is a method parameter with the same name as another method (also in this case should be a duplicate identifier?), it seems that is focused on variables mostly:

Code: Pascal  [Select][+][-]
  1.  
  2.     procedure MethodExample(setvalue: string);
  3.  
  4. implementation
  5.  
  6. procedure TExampleClass.MethodExample(setvalue: string);
  7. begin
  8.   Writeln(setvalue);
  9. end;
  10.  
  11.  

Thank you
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
2 things:
1) Don't use fields in Public section. Use Property
2) Don't use "clear" Parameters-Names. It's easiest to follow FPC-Naming
Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   TExampleClass = class(TObject)
  4.   private
  5.     FField:String;
  6.   public
  7.     Property Field: string Read FField Write FField;
  8.     procedure SetValue(AField: string);  //"AField" is FPC-naming
  9.   end;
  10.  
As to your Question: Probably scoping-collision
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
2 things:
1) Don't use fields in Public section. Use Property
2) Don't use "clear" Parameters-Names. It's easiest to follow FPC-Naming
Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   TExampleClass = class(TObject)
  4.   private
  5.     FField:String;
  6.   public
  7.     Property Field: string Read FField Write FField;
  8.     procedure SetValue(AField: string);  //"AField" is FPC-naming
  9.   end;
  10.  
As to your Question: Probably scoping-collision

Thanks for the suggestions.

Anyway I would stick to the original question, as the conventions are for sure fine, but are not part of the compiler.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Code: Pascal  [Select][+][-]
  1. type
  2.   TExample1 = class(TObject)
  3.   strict private
  4.     FField: string;
  5.   private
  6.     procedure SetField(const AField: string);
  7.   public
  8.     property Field: string read FField write SetField; // here we have a setter
  9.   end;
  10.   TExample2 = class(TObject)
  11.   strict private
  12.     FField: string;
  13.   public
  14.     property Field: string read FField write FField; // here we direct access
  15.   end;
  16.  
  17. implementation
  18.  
  19. procedure TExample1.SetField(const AField: string);
  20. begin
  21.   FField := AField;
  22. end;
Example1 = setter
Example2 = no setter needed
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Code: Pascal  [Select][+][-]
  1. type
  2.   TExample1 = class(TObject)
  3.   strict private
  4.     FField: string;
  5.   private
  6.     procedure SetField(const AField: string);
  7.   public
  8.     property Field: string read FField write SetField; // here we have a setter
  9.   end;
  10.   TExample2 = class(TObject)
  11.   strict private
  12.     FField: string;
  13.   public
  14.     property Field: string read FField write FField; // here we direct access
  15.   end;
  16.  
  17. implementation
  18.  
  19. procedure TExample1.SetField(const AField: string);
  20. begin
  21.   FField := AField;
  22. end;
Example1 = setter
Example2 = no setter needed

This is a modification of the code according to a convention. And is perfectly fine.

But does not answer to my question.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
I beg future answer not to tell about properties/fields in public scope.

This is a convention, a best practice for OOP.

But compiler is another thing, and it allows fields in public scope.

FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
Is it possible to avoid "Error: Duplicate identifier "XXX"" in definition of method SetValue.
Yes it is possible, simple rename it. Now your question is answered I hope.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
I beg future answer not to tell about properties/fields in public scope.

This is a convention, a best practice for OOP.

But compiler is another thing, and it allows fields in public scope.

Moreover I moved Field to private section of the class and I get same error.

Code: Pascal  [Select][+][-]
  1. unit ExampleUnit;
  2.  
  3. {$mode objfpc}
  4.  
  5. interface
  6.  
  7. type
  8.  
  9.   TExampleClass = class(TObject)
  10.   private
  11.     Field: string;
  12.   public
  13.     procedure SetValue(field: string);
  14.   end;
  15.  
  16. implementation
  17.  
  18. procedure TExampleClass.SetValue(field: string);
  19. begin
  20.   Self.Field := field;
  21. end;
  22.  
  23. end.
  24.  

This means that a method param cannot have same name as any variable no matter if is private, protected o public.
« Last Edit: November 29, 2022, 11:32:55 am by tt »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Now your question is answered I hope.

No
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2007
  • Fifty shades of code.
    • Delphi & FreePascal
What you try to do is, simplified
Code: Pascal  [Select][+][-]
  1. function x(const x: string): string;
So why would that not work, have any guess?
The answer to that is the answer to your class question.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Error: Duplicate identifier XXX when method param has same name of variable
« Reply #10 on: November 29, 2022, 11:49:42 am »
BTW I note that it doesn't raise the same error if there is a method parameter with the same name as another method (also in this case should be a duplicate identifier?), it seems that is focused on variables mostly:
Code: Pascal  [Select][+][-]
  1.  
  2.     procedure MethodExample(setvalue: string);
  3.  
  4. implementation
  5.  
  6. procedure TExampleClass.MethodExample(setvalue: string);
  7. begin
  8.   Writeln(setvalue);
  9. end;
  10.  
  11.  

Thank you
Uhmm.... no.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses Classes, SysUtils;
  3. type
  4.  
  5.   { TExampleClass }
  6.  
  7.   TExampleClass = class(TObject)
  8.   public
  9.     Field: string;
  10.     procedure SetValue(Field: String); //Raises "Duplicate identifier"
  11.     Procedure SomeMethod(SetValue:String); //Raises "Duplicate identifier"
  12.   end;
  13.  
  14. { TExampleClass }
  15.  
  16. procedure TExampleClass.SetValue(Field: String);
  17. begin
  18.  
  19. end;
  20.  
  21. procedure TExampleClass.SomeMethod(SetValue: String);
  22. begin
  23.  
  24. end;
  25.  
  26. begin
  27. end.

Bottom Line: Any identifier (Field, Method, Property) within a class can only occur once, except overloads for Methods.
It has to do with Scope of identifier
« Last Edit: November 29, 2022, 11:52:06 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Error: Duplicate identifier XXX when method param has same name of variable
« Reply #11 on: November 29, 2022, 11:51:19 am »
So why would that not work, have any guess?

In Delphi the code I presented compiles successfully. This is the reason why I am asking.

And, also, in Delphi, the code you presented compiles successfully.

See attahced pictures in D7.
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Error: Duplicate identifier XXX when method param has same name of variable
« Reply #12 on: November 29, 2022, 11:53:34 am »
So why would that not work, have any guess?

In Delphi the code I presented compiles successfully. This is the reason why I am asking.

And, also, in Delphi, the code you presented compiles successfully.

See attahced pictures in D7.
because Delphi allows it.

if i insert a {$mode delphi} in my code above, it compiles, too, in Lazarus
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Error: Duplicate identifier XXX when method param has same name of variable
« Reply #13 on: November 29, 2022, 11:57:19 am »
because Delphi allows it.

if i insert a {$mode delphi} in my code above, it compiles, too, in Lazarus

Ok, so I undestand that objfpc mode is more restricting.
Does anybody know why?
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: Error: Duplicate identifier XXX when method param has same name of variable
« Reply #14 on: November 29, 2022, 11:59:35 am »
Bottom Line: Any identifier (Field, Method, Property) within a class can only occur once, except overloads for Methods.
It has to do with Scope of identifier

Ok but a method param should not conflict with class members. Am I wrong?
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

 

TinyPortal © 2005-2018