Recent

Author Topic: I guess I can't initialize variable at declaration of type object  (Read 1761 times)

Weiss

  • Full Member
  • ***
  • Posts: 185
how can I make some variables taking default values for any instance of object? I can do that "manually" by calling some kind of initialization method, but perhaps there is a better way? I was trying something like that
Code: Pascal  [Select][+][-]
  1. type
  2.  
  3. myObject = object
  4. ..
  5. myvariable :integer=10000;
  6. ..
  7. end;
  8.  
  9. var
  10.   object_2 : myObject; // would be nice if myVariable had a default value at this point
  11.  
« Last Edit: August 05, 2024, 06:38:13 am by Weiss »

TRon

  • Hero Member
  • *****
  • Posts: 3643
Re: I guess I can't initialize variable at declaration of type object
« Reply #1 on: August 05, 2024, 07:10:50 am »
...but perhaps there is a better way?
Nope, the way to go is by convention to use the init constructor. see also here (press the up link to read more about old style objects)
« Last Edit: August 05, 2024, 07:14:41 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Khrys

  • Full Member
  • ***
  • Posts: 106
Re: I guess I can't initialize variable at declaration of type object
« Reply #2 on: August 05, 2024, 07:20:53 am »
I'll admit that I've never used legacy  objects, but record initialization syntax seems to work (at least in  {$mode objfpc}):

Code: Pascal  [Select][+][-]
  1. var
  2.   object_2: myObject = (myvariable := 10000);

TRon

  • Hero Member
  • *****
  • Posts: 3643
Re: I guess I can't initialize variable at declaration of type object
« Reply #3 on: August 05, 2024, 07:29:49 am »
I'll admit that I've never used legacy  objects, but record initialization syntax seems to work (at least in  {$mode objfpc}):

Code: Pascal  [Select][+][-]
  1. var
  2.   object_2: myObject = (myvariable := 10000);
Nice find !

Of course, in that case I stand corrected.

To my knowledge this was never possible with BP/Delphi and also seem undocumented (unless counting the generic variable declaration description).
« Last Edit: August 05, 2024, 07:35:22 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

cdbc

  • Hero Member
  • *****
  • Posts: 1666
    • http://www.cdbc.dk
Re: I guess I can't initialize variable at declaration of type object
« Reply #4 on: August 05, 2024, 07:54:37 am »
Hi
You could try:
Code: Pascal  [Select][+][-]
  1. type
  2. type
  3.   myObject = object
  4.     ...
  5.   const
  6.     myvariable : integer = 10000;
  7.     ...
  8.   end;
  9.  
  10. var
  11.   object_2 : myObject; // would be nice if myVariable had a default value at this point
  12.  
It used to be called 'writable const' but now I think it's become 'static var' and {$J+} is default in {$mode objfpc}
Regards Benny
« Last Edit: August 05, 2024, 07:56:18 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

440bx

  • Hero Member
  • *****
  • Posts: 4740
Re: I guess I can't initialize variable at declaration of type object
« Reply #5 on: August 05, 2024, 07:56:50 am »
Using record initialization to initialize an object is a nice feature but, it also requires every field to be initialized.

This statement from the OP:
Code: Text  [Select][+][-]
  1. how can I make some variables taking default values for any instance of object?
gives the impression that he'd like to initialize only "some" of the fields.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

TRon

  • Hero Member
  • *****
  • Posts: 3643
Re: I guess I can't initialize variable at declaration of type object
« Reply #6 on: August 05, 2024, 08:11:40 am »
Using record initialization to initialize an object is a nice feature but, it also requires every field to be initialized.
Strangely enough no. Usually you get a message in the likes of some fields after x are not initialized but you even seem to be able to skip in between.

edit: Although on second thought it makes sense because fields in oldstyle objects are initialized.

I'm more upset with myself by the fact that I've never tried to initialize old-style objects this way.
« Last Edit: August 05, 2024, 08:22:53 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Weiss

  • Full Member
  • ***
  • Posts: 185
Re: I guess I can't initialize variable at declaration of type object
« Reply #7 on: August 05, 2024, 10:31:00 pm »
thank you gents. I understand there is property that can store the default value for a variable? something like

Code: Pascal  [Select][+][-]
  1. type
  2.   myObject = object
  3.     ...
  4.       myvariable : integer;
  5.     ...
  6. property variable : integer read myvariable write setMyVariable default 10000;
  7.   end;
  8.  
  9. var
  10.   object_2 : myObject; // myVariable is still at 0
  11.  
  12.  

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: I guess I can't initialize variable at declaration of type object
« Reply #8 on: August 06, 2024, 01:17:55 am »
Yes it would be nice of the old objects would support operators because they can do inherited things where the records don't.

Consider this as an auto constructor and destructor where you can make auto created objects via records. As you know, records can have most everything interesting, but not inheritance. However, the example I show below is a somewhat example of using a record to contains one or more classes which can be managed in the scope and there for, no need to fiddle with this things.

Almost like multiple inheritance in C++  :o

Code: Pascal  [Select][+][-]
  1.  
  2. unit Unit1;
  3.  
  4. {$mode objfpc}{$H+}
  5. {$ModeSwitch advancedRecords}
  6.  
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  11.  
  12. type
  13.  
  14.     { myObject }
  15.  
  16.     myObject = record
  17.     myvariable : integer;
  18.     M:TMemoryStream;
  19.     class operator Initialize (var Dest: MyObject);
  20.     Class operator Finalize(Var Dest:myObject);
  21.     End;
  22.  
  23.   { TForm1 }
  24.  
  25.   TForm1 = class(TForm)
  26.     Button1: TButton;
  27.     procedure Button1Click(Sender: TObject);
  28.   private
  29.  
  30.   public
  31.  
  32.   end;
  33.  
  34. var
  35.   Form1: TForm1;
  36.  
  37. implementation
  38.  
  39. {$R *.lfm}
  40.  
  41. { myObject }
  42.  
  43. class operator myObject.Initialize(var Dest: MyObject);
  44. begin
  45.   Dest.Myvariable :=42;
  46.   Dest.M := TMemoryStream.Create;
  47. end;
  48.  
  49. class operator myObject.Finalize(var Dest: myObject);
  50. begin
  51.   Dest.M.Free;
  52. end;
  53.  
  54. { TForm1 }
  55.  
  56. procedure TForm1.Button1Click(Sender: TObject);
  57. Var
  58.   object_2 : myObject;
  59. begin
  60.   Caption := object_2.Myvariable.Tostring;  {which displays 42}
  61.   //and no memory leaks from the memorystream when exiting.!
  62. end;
  63.  
  64. end.
  65.  
  66.  

The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 16189
  • Censorship about opinions does not belong here.
Re: I guess I can't initialize variable at declaration of type object
« Reply #9 on: August 06, 2024, 02:34:43 pm »
You can do this of course, slightly editted later:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode objfpc}{$modeswitch advancedrecords}{$endif}
  2. type    
  3.   Tmyobject = object
  4.   type
  5.     TInnerRecord = record
  6.      a,b:integer;
  7.      class operator Initialize(var value:TmyObject.TInnerRecord);
  8.    end;
  9.    var
  10.      InnerRecord:TInnerRecord;
  11.   end;
  12.  
  13.   class operator TMyObject.TInnerRecord.Initialize(var value:TMyObject.TInnerRecord);
  14.   begin
  15.     value.a :=100;
  16.     value.b :=200;
  17.   end;
  18. var
  19.   O:TmyObject;
  20. begin
  21.   writeln(O.InnerRecord.a);
  22.   writeln(O.InnerRecord.b);  
  23. end.
« Last Edit: August 06, 2024, 02:47:14 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Thaddy

  • Hero Member
  • *****
  • Posts: 16189
  • Censorship about opinions does not belong here.
Re: I guess I can't initialize variable at declaration of type object
« Reply #10 on: August 06, 2024, 02:55:12 pm »
Or:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode objfpc}{$modeswitch advancedrecords}{$endif}
  2. type    
  3.   Tmyobject = object
  4.   type
  5.     TInnerRecord = record
  6.      a,b:integer;
  7.      class operator Initialize(var value:TmyObject.TInnerRecord);
  8.    end;
  9.    private
  10.     InnerRecord:TInnerRecord;
  11.    public
  12.     property a:integer read InnerRecord.a;
  13.     property b:integer read InnerRecord.b;
  14.   end;
  15.  
  16.   class operator TMyObject.TInnerRecord.Initialize(var value:TMyObject.TInnerRecord);
  17.   begin
  18.     value.a :=100;
  19.     value.b :=200;
  20.   end;
  21. var
  22.   O:TmyObject;
  23. begin
  24.   writeln(O.a);
  25.   writeln(O.b);  
  26. end.
« Last Edit: August 06, 2024, 02:56:49 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: I guess I can't initialize variable at declaration of type object
« Reply #11 on: August 07, 2024, 12:21:31 am »
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeSwitch AdvancedRecords}
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11. TmyObject = object
  12. Type
  13.       stub= Record
  14.       class operator initialize(Var theobj:stub);
  15.       End;
  16. Private
  17.   {Place no substances above this}
  18.   Fake:Stub; {Marks the start of the Object}
  19. Public
  20.   x,y:Integer;
  21.  
  22. end;
  23.  
  24.   { TForm1 }
  25.  
  26.   TForm1 = class(TForm)
  27.     Button1: TButton;
  28.     procedure Button1Click(Sender: TObject);
  29.   private
  30.  
  31.   public
  32.  
  33.   end;
  34.  
  35. var
  36.   Form1: TForm1;
  37.  
  38. implementation
  39.  
  40. {$R *.lfm}
  41.  
  42. { TmyObject.M }
  43.  
  44. class operator TmyObject.Stub.initialize(var theobj: Stub);
  45. Var
  46.   T:^TmyObject;
  47. begin
  48.   T:=(@TheObj);
  49.   T^.x := 42;
  50.   T^.y := 45;
  51. end;
  52.  
  53. { TForm1 }
  54.  
  55. procedure TForm1.Button1Click(Sender: TObject);
  56. Var
  57.   MyObject:TMyObject;
  58. begin
  59.   Caption := Myobject.x.ToString+','+MyObject.y.Tostring;
  60. end;
  61.  
  62. end.
  63.  
  64.  
  65.  

DIfferent but the same with less details for accessing.

EDIT:
 This most likely will not work if inheritance is in play here unless the define is in the first parent, in which case, one could write a base object just as for auto initializer
« Last Edit: August 07, 2024, 12:25:41 am by jamie »
The only true wisdom is knowing you know nothing

Weiss

  • Full Member
  • ***
  • Posts: 185
Re: I guess I can't initialize variable at declaration of type object
« Reply #12 on: August 07, 2024, 07:33:45 am »
Or:

Neat. My head spinning, with inner records and nested types, a lot of info. Thank you again. This auto initialization was on my mind, never knew which question to ask, and here it is.

Weiss

  • Full Member
  • ***
  • Posts: 185
Re: I guess I can't initialize variable at declaration of type object
« Reply #13 on: August 07, 2024, 08:03:33 am »
Yes it would be nice of the old objects would support operators because they can do inherited things where the records don't.

Consider this as an auto constructor and destructor where you can make auto created objects via records.

Code: Pascal  [Select][+][-]
  1.  
  2. unit Unit1;
  3. ...
  4.     M:TMemoryStream;
  5.   ..
  6.  
  7.   Dest.M := TMemoryStream.Create;
  8. ..
  9.  
  10. class operator myObject.Finalize(var Dest: myObject);
  11. begin
  12.   Dest.M.Free;
  13. end;
  14.  
  15. { TForm1 }
  16.  
  17.  
  18. end;
  19.  
  20. end.
  21.  
  22.  



Jamie, why did we need stream in your example? sorry for stupid questions

Thaddy

  • Hero Member
  • *****
  • Posts: 16189
  • Censorship about opinions does not belong here.
Re: I guess I can't initialize variable at declaration of type object
« Reply #14 on: August 07, 2024, 08:34:01 am »
Neat. My head spinning, with inner records and nested types, a lot of info. Thank you again. This auto initialization was on my mind, never knew which question to ask, and here it is.

Although my previous example is syntactically correct, you do not need to use fully qualified names. Here is a cleaned up version that may be easier to understand:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$modeswitch advancedrecords}{$warn 5090 off}
  2. type    
  3.   TMyObject = object
  4.     type
  5.       TInnerRecord = record
  6.         a,b:integer;
  7.         class operator Initialize(var value:TInnerRecord);
  8.       end;
  9.    strict private
  10.      InnerRecord:TInnerRecord;
  11.    public
  12.      property a:integer read InnerRecord.a write InnerRecord.a;
  13.      property b:integer read InnerRecord.b write InnerRecord.b;
  14.   end;
  15.  
  16.   class operator TMyObject.TInnerRecord.Initialize(var value:TInnerRecord);
  17.   begin
  18.     value.a :=100;
  19.     value.b :=200;
  20.   end;
  21.  
  22. var
  23.   O:TmyObject;
  24. begin
  25.   writeln(O.a);
  26.   writeln(O.b);  
  27. end.
Basically what we do here is move all or any object fields into a local record. This has no effect on performance. These fields can - if necessary - subsequently be initialized through the management operator. I designed it such that the record itself need not be exposed to the outer world, just like you would usually do with normal fields.
The main difference between a constructor and the managed record is that the constructor would be called on a pointer to object, or need to be called manually whereas the management operator is automatically called on the object variable itself.
something like :
Code: Pascal  [Select][+][-]
  1. var PO:PMyObject;
  2. begin
  3.   PO :=New(PMyObject, Init);// contructor
  4.   ...
  5.   Dispose(PO,Done);// destructor
  6. // or
  7.   O:TMyObject;
  8. begin
  9.   O.Init;// needs to be called manually
With the record, we can also use the finalize management operator instead of a destructor.
It is not just syntactic sugar: this makes your code safer since you do not have to remember to call the constructor and/or destructor for the object. (That is, except if the object is created with New(), In that case you would still need to call Dispose()... )
« Last Edit: August 07, 2024, 10:10:25 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

 

TinyPortal © 2005-2018