Recent

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

flowCRANE

  • Hero Member
  • *****
  • Posts: 986
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 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1225
    • 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: 2510
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: 1225
    • 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: 2510
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: 19431
  • Glad to be alive.
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 »
Any "programmer" that knows only one programming language is not a programmer

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1225
    • 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: 19431
  • Glad to be alive.
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 »
Any "programmer" that knows only one programming language is not a programmer

ASerge

  • Hero Member
  • *****
  • Posts: 2510
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: 19431
  • Glad to be alive.
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}
Any "programmer" that knows only one programming language is not a programmer

PascalDragon

  • Hero Member
  • *****
  • Posts: 6403
  • 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: 19431
  • Glad to be alive.
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.
Any "programmer" that knows only one programming language is not a programmer

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1225
    • 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