Recent

Author Topic: Record with methods?  (Read 39688 times)

furious programming

  • Hero Member
  • *****
  • Posts: 858
Re: Record with methods?
« Reply #30 on: March 22, 2018, 01:15:19 pm »
@Paul_: you can use {$MODE OBJFPC} and {$MODESWITCH ADVANCEDRECORDS} to force support records with methods (and not only):

Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}{$MODESWITCH ADVANCEDRECORDS}
  2.  
  3. type
  4.   TAdvancedRecord = record
  5.   private
  6.     FField: Integer;
  7.   public
  8.     procedure Method();
  9.   end;

If you want to use a universal structure (and backward compatible) then use classic objects:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSimpleObject = object
  3.   private
  4.     FField: Integer;
  5.   public
  6.     procedure Method();
  7.   end;

There is no need to use delphi mode.
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Record with methods?
« Reply #31 on: March 22, 2018, 05:22:06 pm »
Also, if you use OBJECT take care with what marcov said:
Note that a danger of using TP objects instead of records with methods is that TP objects are not safe with automated types (ansistrings, dynamic arrays). So I wouldn't recommend this.
This means you must initialize your OBJECT's arrays and strings and such properly to avoid problems.
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Record with methods?
« Reply #32 on: March 22, 2018, 06:02:17 pm »
This means you must initialize your OBJECT's arrays and strings and such properly to avoid problems.
Give an example with an error, please.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Record with methods?
« Reply #33 on: March 23, 2018, 10:51:28 am »
Code: Pascal  [Select][+][-]
  1. PROGRAM Test;
  2.  
  3.   TYPE
  4.     TMyObject = OBJECT Name: STRING; END;
  5.  
  6.   VAR
  7.     AnObject: TMyObject;
  8.  
  9. BEGIN
  10.   WriteLn ('Name: "', AnObject.Name, '"')
  11. END.
  12.  
Note that the example may behave as expected (i.e. write 'Name: ""' on console) but it depends on what you do before and what OS are you using.  The thing here is that "Name" may contain garbage because it isn't initialized.

Same example with advanced records:
Code: Pascal  [Select][+][-]
  1. PROGRAM Test;
  2.  
  3.   TYPE
  4.     TMyObject = RECORD Name: STRING; END;
  5.  
  6.   VAR
  7.     AnObject: TMyObject;
  8.  
  9. BEGIN
  10.   WriteLn ('Name: "', AnObject.Name, '"')
  11. END.
  12.  
That will work as expected always, because "Name" is initialized.

Also you can "fix" it by using the OBJECT constructor and destructor but I (we) really recommend not to use OBJECT and use CLASS or RECORD instead.
« Last Edit: March 23, 2018, 10:57:45 am by Ñuño_Martínez »
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Record with methods?
« Reply #34 on: March 23, 2018, 05:43:08 pm »
...may behave as expected, ...may contain garbage because it isn't initialized.
About nothing  ;D

Let's take an example:
Code: Pascal  [Select][+][-]
  1. program project2;
  2. {$MODE FPC}
  3. {$APPTYPE CONSOLE}
  4.  
  5. type
  6.   TObj = object
  7.     Name: string;
  8.   end;
  9.  
  10.   TRec = record
  11.     Name: string;
  12.   end;
  13.  
  14. procedure Test;
  15. var
  16.   Obj: TObj;
  17.   Rec: TRec;
  18. begin
  19.   Writeln('Name obj: <', Obj.Name, '>');
  20.   Writeln('Name rec: <', Rec.Name, '>');
  21.   Readln;
  22. end;
  23.  
  24. begin
  25.   Test;
  26. end.

1. Mode is FPC (default for you test also). String is ShortString! (not reference type). In this case, the value of the variable is undefined (by definition). We see garbage in both cases. In your example, the variables are global and are cleared for this reason. But in any case, their behavior is the same!
2. Add {$LONGSTRINGS ON}. Yes, everything was clean! Again, in both cases.

Give a real, rather than a hypothetical example, where an objects are working with an error, and a records without error.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Record with methods?
« Reply #35 on: March 23, 2018, 06:13:33 pm »
Oh well (Fleetwood Mac)

- 1. records do not have to be initialized. Even advanced records.

Simple as that... <AND VERY GRUMPY!!! >:D >:D >:D >:D>

If old hands start to do the wrong things there is something really wrong here. STOP IT.
We have a language and it works as advertised.

If you want to play try the operators in trunk...<whiley, somber> which are great for people with brains. (working brains)
Hey, it's Friday... O:-) 8-) And I get less sleep this weekend... :o
« Last Edit: March 23, 2018, 06:19:36 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Record with methods?
« Reply #36 on: March 26, 2018, 12:12:37 pm »
Give a real, rather than a hypothetical example, where an objects are working with an error, and a records without error.
Ok, I did it and I have unspected results (on Linux)  %):
Code: Pascal  [Select][+][-]
  1. PROGRAM TestProgram;
  2. PROGRAM TestProgram;
  3. (* Program to test data corruption on OBJECT and RECORD. *)
  4.     {$MODE FPC}
  5.     {$APPTYPE CONSOLE}
  6.  
  7.   TYPE
  8.   (* Define a simple non-initializable object. *)
  9.     TObj = OBJECT Data: STRING END;
  10.   (* Define a simple record. *)
  11.     TRec = RECORD Data: STRING END;
  12.  
  13. (* Shows data. *)
  14.   PROCEDURE ShowData (Obj: TObj; Rec: TRec);
  15.   BEGIN
  16.     WriteLn ('Obj.Data = "', Obj.Data, '"');
  17.     WriteLn ('Rec.Data = "', Rec.Data, '"');
  18.     WriteLn
  19.   END;
  20.  
  21.  
  22.  
  23. (* Test 1:  Using data without initialization. *)
  24.   PROCEDURE TestNoInitialize;
  25.   VAR
  26.     Obj: TObj;
  27.     Rec: TRec;
  28.   BEGIN
  29.     Writeln ('TestNoInitialize');
  30.     Writeln ('================');
  31.     ShowData (Obj, Rec)
  32.   END;
  33.  
  34.  
  35.  
  36. (* Test 2: Initialize data then use. *)
  37.   PROCEDURE TestInitialize;
  38.   VAR
  39.     Obj: TObj;
  40.     Rec: TRec;
  41.   BEGIN
  42.     Writeln ('TestInitialize');
  43.     Writeln ('==============');
  44.     Obj.Data := 'Object.Data';
  45.     Rec.Data := 'Rect.Data';
  46.     ShowData (Obj, Rec)
  47.   END;
  48.  
  49. VAR
  50.   Obj: TObj;
  51.   Rec: TRec;
  52. BEGIN
  53.   Writeln ('Global');
  54.   Writeln ('======');
  55.   ShowData (Obj, Rec);
  56.   WriteLn ('******************************');
  57.   TestNoInitialize;
  58.   WriteLn ('******************************');
  59.   TestInitialize;
  60.   WriteLn ('******************************');
  61.   TestNoInitialize;
  62.   WriteLn ('******************************');
  63.   Writeln ('Global');
  64.   Writeln ('======');
  65.   ShowData (Obj, Rec);
  66.   Write ('Press Intro to continue...');
  67.   ReadLn
  68. END.
  69.  

Output I got:
Code: [Select]
Global
======
Obj.Data = ""
Rec.Data = ""

******************************
TestNoInitialize
================
Obj.Data = ""
Rec.Data = "�s��A"

******************************
TestInitialize
==============
Obj.Data = "Object.Data"
Rec.Data = "Rect.Data"

******************************
TestNoInitialize
================
Obj.Data = "Object.Data"
Rec.Data = "Rect.Data"

******************************
Global
======
Obj.Data = ""
Rec.Data = ""

Press Intro to continue...
As I've said, unspected...
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Record with methods?
« Reply #37 on: March 26, 2018, 12:29:10 pm »
The fact that the record is not initialized you mean? That's dirty stackspace. Fully predictable. That's what the default() intrinsic is for. What you should have done is add a method and see what happens.
The difference between advanced records and plain records. Also note I can just test with trunk and there I get clean output under Linux (and windows 64 too).
Code: Bash  [Select][+][-]
  1. Global
  2. ======
  3. Obj.Data = ""
  4. Rec.Data = ""
  5.  
  6. ******************************
  7. TestNoInitialize
  8. ================
  9. Obj.Data = ""
  10. Rec.Data = ""
  11.  
  12. ******************************
  13. TestInitialize
  14. ==============
  15. Obj.Data = "Object.Data"
  16. Rec.Data = "Rect.Data"
  17.  
  18. ******************************
  19. TestNoInitialize
  20. ================
  21. Obj.Data = "Object.Data"
  22. Rec.Data = "Rect.Data"
  23.  
  24. ******************************
  25. Global
  26. ======
  27. Obj.Data = ""
  28. Rec.Data = ""
  29.  
  30. Press Intro to continue...
  31.  
« Last Edit: March 26, 2018, 12:58:38 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

ASerge

  • Hero Member
  • *****
  • Posts: 2242
Re: Record with methods?
« Reply #38 on: March 26, 2018, 05:52:31 pm »
Ok, I did it and I have unspected results (on Linux)  %):
I quote myself  8):
Quote
...String is ShortString! (not reference type). In this case, the value of the variable is undefined (by definition).
And the compiler warns about the same!
Replace with the reference type AnsiString and check to see if there is any difference.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Record with methods?
« Reply #39 on: March 26, 2018, 06:11:42 pm »
His code is {$mode fpc} and that is shortstring by default. As opposed to {$mode delphi} and {$mode objfpc}
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: Record with methods?
« Reply #40 on: April 06, 2018, 04:45:07 pm »
Mode ObjFPC also has String = ShortString by default.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: Record with methods?
« Reply #41 on: April 06, 2018, 05:05:01 pm »
Ok. I believed otherwise but I stand corrected. Note I believe he is using fpc mode.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Record with methods?
« Reply #42 on: April 10, 2018, 12:53:25 pm »
In any case, I was wrong with some of my statements.  :-[
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

 

TinyPortal © 2005-2018