Recent

Author Topic: How to assign to record elements using brackets?  (Read 5816 times)

Akira1364

  • Hero Member
  • *****
  • Posts: 563
How to assign to record elements using brackets?
« on: December 24, 2015, 08:28:45 pm »
Let's say I've defined:

type
    ExampleRecord = record
        StringElement: String;
        IntElement: Integer;
    end;


If I try to do something like:

AnExampleRecord := ExampleRecord('AString', 5);

The compiler says Fatal: Syntax error, ")" expected but "," found

Instead I'm forced to do:

AnExampleRecord := ExampleRecord;
AnExampleRecord.StringElement := 'AString';
AnExampleRecord.IntElement := 5;


Do I need to use {$MODE Delphi} or something to be able to do it the first way? Or is there a specific individual compiler flag I can set?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8819
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to assign to record elements using brackets?
« Reply #1 on: December 24, 2015, 08:37:32 pm »
Record initialization is only supported on declaration sections (const, var). If you want to do like what you've shown, create a function for it (See Classes.Point and Classes.Rect how they return filled TPoint and TRect records, respectively).

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: How to assign to record elements using brackets?
« Reply #2 on: December 24, 2015, 08:44:32 pm »
Code: [Select]
program records;

Type
 TExampleRecord = record
      StringElement: String;
      IntElement: Integer;
 end;

Var
  x : TExampleRecord =
  (
    StringElement: 'hello';
    IntElement   : 100;
  ); 

  y : Array[1..10] of TExampleRecord =
  (
    ( StringElement: 'One'  ; IntElement  : 1),
    ( StringElement: 'Two'  ; IntElement  : 2),
    ( StringElement: 'Three'; IntElement  : 3),
    ( StringElement: 'Four' ; IntElement  : 4),
    ( StringElement: 'Five' ; IntElement  : 5),
    ( StringElement: 'Six'  ; IntElement  : 6),
    ( StringElement: 'Seven'; IntElement  : 7),
    ( StringElement: 'Eight'; IntElement  : 8),
    ( StringElement: 'Nine' ; IntElement  : 9),
    ( StringElement: 'Ten'  ; IntElement  : 10)
  );

begin
  With x do
  begin
    StringElement := 'bye';
    IntElement    := -1;
  end;
end.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: How to assign to record elements using brackets?
« Reply #3 on: December 25, 2015, 08:26:01 am »
Use record as a class definition

Code: [Select]
type
    ExampleRecord = record
        StringElement: String;
        IntElement: Integer;
        procedure Add(const aString : string; const aValue : integer);
    end;

ExampleRecord.Add(const aString : string; const aValue : integer);
begin
      StringElement := aString;
      IntElement      := aInteger;
end;

procedure foo;
var AnExampleRecord : ExampleRecord;
begin
  AnExampleRecord.add('AString', 5);
end;
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

guest58172

  • Guest
Re: How to assign to record elements using brackets?
« Reply #4 on: December 25, 2015, 09:18:22 am »
Do I need to use {$MODE Delphi} or something to be able to do it the first way? Or is there a specific individual compiler flag I can set?

Yes, you need to enable advanced records, also you must define a static function that allows to use the type:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$MODE OBJFPC}
  3. {$modeswitch advancedrecords}
  4.  
  5. type
  6.   TFoo = record
  7.       StringElement: String;
  8.       IntElement: Integer;
  9.       class function init(const aString : string; const aValue : integer): TFoo; static;
  10.   end;
  11.  
  12. class function TFoo.init(const aString : string; const aValue : integer): TFoo;
  13. begin
  14.   result.IntElement:= aValue;
  15.   result.StringElement:= aString;
  16. end;
  17.  
  18. var
  19.   foo: TFoo;
  20. begin
  21.   foo := TFoo.init('a', 1);
  22. end.  
  23.  

As an alternative, for example if you want to make this on a library type (which cannot be modified) you can use a record helper:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$MODE OBJFPC}
  3. {$modeswitch advancedrecords}
  4.  
  5. type
  6.   TFoo = record
  7.       StringElement: String;
  8.       IntElement: Integer;
  9.   end;
  10.  
  11.   TFooHlp = record helper for TFoo
  12.     class function init(const aString : string; const aValue : integer): TFoo; static;
  13.   end;
  14.  
  15. class function TFooHlp.init(const aString : string; const aValue : integer): TFoo;
  16. begin
  17.   result.IntElement:= aValue;
  18.   result.StringElement:= aString;
  19. end;
  20.  
  21. var
  22.   foo: TFoo;
  23. begin
  24.   foo := TFoo.init('a', 1);
  25. end.
  26.  

FTurtle

  • Sr. Member
  • ****
  • Posts: 292
Re: How to assign to record elements using brackets?
« Reply #5 on: December 25, 2015, 10:24:52 am »
If you want to do like what you've shown, create a function for it (See Classes.Point and Classes.Rect how they return filled TPoint and TRect records, respectively).
I think this is the best solution.

Code: Pascal  [Select][+][-]
  1. type
  2.   TExampleRecord = record
  3.     StringElement: String;
  4.     IntElement: Integer;
  5.   end;
  6.  
  7. function ExampleRecord(AStringElement: String; AIntElement: Integer): TExampleRecord;
  8.   begin
  9.     with Result do
  10.     begin
  11.       StringElement := AStringElement;
  12.       IntElement := AIntElement;
  13.     end;
  14. end;
  15.  
  16. procedure DoSomething;
  17. var
  18.   r: TExampleRecord;
  19. begin
  20.   r := ExampleRecord('AString', 5);
  21.  

guest58172

  • Guest
Re: How to assign to record elements using brackets?
« Reply #6 on: December 25, 2015, 12:50:57 pm »
If you want to do like what you've shown, create a function for it (See Classes.Point and Classes.Rect how they return filled TPoint and TRect records, respectively).
I think this is the best solution.

Code: Pascal  [Select][+][-]
  1. type
  2.   TExampleRecord = record
  3.     StringElement: String;
  4.     IntElement: Integer;
  5.   end;
  6.  
  7. function ExampleRecord(AStringElement: String; AIntElement: Integer): TExampleRecord;
  8.   begin
  9.     with Result do
  10.     begin
  11.       StringElement := AStringElement;
  12.       IntElement := AIntElement;
  13.     end;
  14. end;
  15.  
  16. procedure DoSomething;
  17. var
  18.   r: TExampleRecord;
  19. begin
  20.   r := ExampleRecord('AString', 5);
  21.  

With my solution you can directly work on type, e.g with with TFoo.init de ;. But it looks like you don't know static function yet.

FTurtle

  • Sr. Member
  • ****
  • Posts: 292
Re: How to assign to record elements using brackets?
« Reply #7 on: December 25, 2015, 01:30:56 pm »
But it looks like you don't know static function yet.
This is wrong assumption.
I'd prefer keep standalone function as external utility.
As for method, I'd prefer usual method instead static:

Code: Pascal  [Select][+][-]
  1. type
  2.   TFoo = record
  3.       StringElement: String;
  4.       IntElement: Integer;
  5.       procedure Init(const aString : string; const aValue : integer);
  6.   end;
  7.  
  8. procedure TFoo.Init(const aString : string; const aValue : integer);
  9. begin
  10.   IntElement:= aValue;
  11.   StringElement:= aString;
  12. end;
  13.  
  14. var
  15.   foo: TFoo;
  16. begin
  17.   foo.Init('a', 1);
  18.  

Akira1364

  • Hero Member
  • *****
  • Posts: 563
Re: How to assign to record elements using brackets?
« Reply #8 on: December 25, 2015, 05:44:32 pm »
Thanks everyone.. i should be able to figure out a solution for my application based on a combination of your advice. BBasile's method specifically reminds me very much of Python class initialization, which I'm quite familiar with.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: How to assign to record elements using brackets?
« Reply #9 on: December 26, 2015, 10:58:44 am »
But BBasile doesn't look to an array structure, only record structure. FTurtle's and mine code  are static functions and doesn't bother with array you're working.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

 

TinyPortal © 2005-2018