Recent

Author Topic: I found something clever! short way to define a RECORD with a couple of values.  (Read 954 times)

jamie

  • Hero Member
  • *****
  • Posts: 6516
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeSwitch AdvancedRecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  TMyRecord = Record
  15.   x,Y:Integer;
  16.   Function fReadXY(xx,yy:Integer):TMyRecord; inline;
  17.   Public
  18.   property XY[xx,yy:integer]:TMyRecord read freadXY; default;
  19.  end;
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     procedure Button1Click(Sender: TObject);
  24.   private
  25.  
  26.   public
  27.  
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34. {$R *.lfm}
  35. Function TMyRecord.fReadXY(xx,yy:Integer):TMyRecord;
  36. Begin
  37.  x := xx;
  38.  y := yy;
  39.  result := Self;
  40. End;
  41. { TForm1 }
  42. Procedure Displayit(AR:TMyRecord); overload;
  43. begin
  44.   Form1.Caption := Ar.x.Tostring+','+AR.y.Tostring;
  45. end;
  46. procedure TForm1.Button1Click(Sender: TObject);
  47. Var
  48.   Y,Z:TMyrecord;
  49. begin
  50.   Y[10,40]; // this works;
  51.   DisplayiT(Z[1000,45]);// This works as value
  52. end;
  53.  
  54. end.
  55.  
  56.  
Now I can Add the constructor in there so that we can create parametrize instances, but I found this interesting because I can assign and test it inline with an if statement I believe, Haven't don't that yet
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6516
An update to this use.
The records I have do have Constructors already and I found that I did not need to add a function, I can call the constructor and it works the same it seems. so no need to add a function.

Code: Pascal  [Select][+][-]
  1. // within the Reocord
  2. Property C[x,y:Integer]:TMyPoint Read Create; default;
  3.  

With that you can shorthand the call to the Constructor.

so in code

Code: Pascal  [Select][+][-]
  1. Var
  2.  A,B:TMyPoint;
  3. Begin
  4.   A[x,y];
  5.   B:= A[x,y]
  6.  //on so on.
  7.  

This saves me tons of typing !

Also, I noticed it only works with a READ accessor, Write accessor does not seem to be accepted.
The only true wisdom is knowing you know nothing

JdeHaan

  • Full Member
  • ***
  • Posts: 136
Nice idea!

Code: Pascal  [Select][+][-]
  1. program records;
  2. {$mode delphi}
  3.  
  4.   TLocal = record
  5.     Name: ShortString;
  6.     Level: Integer;
  7.     Captured: Boolean;
  8.     constructor Create(aName: String; aLevel: Integer; aCaptured: Boolean);
  9.     property Value[aName: String; aLevel: Integer; aCaptured: Boolean]:TLocal read Create; default;
  10.   end;
  11.  
  12. constructor TLocal.Create(aName: String; aLevel: Integer; aCaptured: Boolean);
  13. begin
  14.   Name := aName;
  15.   Level := aLevel;
  16.   Captured := aCaptured;
  17. end;
  18.  
  19. var
  20.   Local: TLocal;
  21.  
  22. begin
  23.   Local['Name', 42, True];
  24.   Writeln(Local.Name, ', ', Local.Level, ', ', Local.Captured);
  25. end.
  26.  

It works with ShortString fields, but not with fields of type String.

jamie

  • Hero Member
  • *****
  • Posts: 6516
Managed types, I never tried that. I normally use primitive types.


you could try to prefix the NAME with Self.NAME := aName;

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6516
You may want to try using the DEFAULT(Self) while in the constructor before setting the strings.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6516
It seems a Constructor does not work well with managed types.

back to using a function instead which works for managed types.
The only true wisdom is knowing you know nothing

JdeHaan

  • Full Member
  • ***
  • Posts: 136
Confirmed: with a function you can use a managed type.

Code: Pascal  [Select][+][-]
  1.   TLocal = record
  2.     Name: String;
  3.     Level: Integer;
  4.     Captured: Boolean;
  5.     function Init(aName: String; aLevel: Integer; aCaptured: Boolean): TLocal;
  6.     property Value[aName: String; aLevel: Integer; aCaptured: Boolean]:TLocal read Init; default;
  7.   end;
  8.  
  9. function TLocal.Init(aName: String; aLevel: Integer; aCaptured: Boolean): TLocal;
  10. begin
  11.   Name := aName;
  12.   Level := aLevel;
  13.   Captured := aCaptured;
  14.   Result := Self;
  15. end;
  16.  
  17. begin
  18.   Local['Name', 42, True];
  19.   Writeln(Local.Name, ', ', Local.Level, ', ', Local.Captured);
  20.   // prints 'name', 42, true
  21. end.
  22.  

 

TinyPortal © 2005-2018