Lazarus

Programming => General => Topic started by: iru on January 12, 2019, 12:06:18 am

Title: [Solved] Class Property problems
Post by: iru on January 12, 2019, 12:06:18 am
Gentlefolk,

I have a problem with a 'property' when trying to access 'private' data on a class definition.

Environment: Linux Mint 19, Laz 1.8.4.

The code is:
  TEventsDM = class(TDataModule)
    ..
  private
    fCurrentEvent : tDataResults;
    Procedure SetCurr(InData : tDataResults);
    Function  GetCurr : tDataResults;
  public
    constructor Create(Sender: TObject);
 
    property SetCurrent : tDataResults read GetCurr write SetCurr;
    property GetCurrent : tDataResults read GetCurr write SetCurr;
  end;

  EventsDM : TEventsDM;

And SetCurr and GetCurr code.

The above code compiles clean but the compiler complains about the following

  EventsDM.SetCurrent(...);  with  '(found, expecting ;'.

Remove the (...) and the code compiles clean but when stepped through in the debugger executes the code for GetCurrent.

If I try and tidy up the property/s to

    property SetCurrent : tDataResults write SetCurr;
    property GetCurrent : tDataResults read GetCurr; 

The compile fails reporting    'No member is provided to access property'.

Any help appreciated, Ian.


               
Title: Re: Class Property problems
Post by: Blaazen on January 12, 2019, 12:33:33 am
I can't see anything wrong with the code (ommiting the fact that two properties have the same getter and setter). It compiles well. However, naming of properties Get... and Set... is confusing.

And this:
Code: Pascal  [Select][+][-]
  1. property SetCurrent : tDataResults write SetCurr;
  2.  
is nonsense, or at least very unusual. A write-only property.
Title: Re: Class Property problems
Post by: dsiders on January 12, 2019, 12:47:13 am
  TEventsDM = class(TDataModule)
    ..
  private
    fCurrentEvent : tDataResults;
    Procedure SetCurr(InData : tDataResults);
    Function  GetCurr : tDataResults;
  public
    constructor Create(Sender: TObject);
 
    property SetCurrent : tDataResults read GetCurr write SetCurr;
    property GetCurrent : tDataResults read GetCurr write SetCurr;
  end;

  EventsDM : TEventsDM;

You just need to clean up the property definition.

Code: [Select]
  TEventsDM = class(TDataModule)
    fCurrentEvent: tDataResults;
  private
    procedure SetCurrentEvent(AData: tDataResults);
    function  GetCurrentEvent: tDataResults;
  public
    constructor Create(Sender: TObject);
    property CurrentEvent: tDataResults read GetCurrentEvent write SetCurrentEvent;
  end;
Title: Re: Class Property problems
Post by: jamie on January 12, 2019, 01:01:01 am
Its strange that compiler is getting confused on that Hmm....

 Also I don't know if you are handling the inherited create or not?

 are you calling the inherited create somewhere ?


Title: Re: Class Property problems
Post by: lucamar on January 12, 2019, 01:08:21 am
The problem with your code is that you're trying to access a property as if it where a function and that not only can't be done but doesn't make sense either: that's what the getter/setter are for. Using the (more correct) format:

Code: Pascal  [Select][+][-]
  1. TEventsDM = class(TDataModule)
  2.     ..
  3.   private
  4.     fCurrentEvent : tDataResults;
  5.     Procedure SetCurr(InData : tDataResults);
  6.     Function  GetCurr : tDataResults;
  7.   public
  8.     constructor Create(Sender: TObject);
  9.  
  10.     property Current : tDataResults read GetCurr write SetCurr;
  11.   end;
  12.  
  13.   EventsDM : TEventsDM;

when your other code reads or writes EventsDM.Current, as in:
Code: Pascal  [Select][+][-]
  1. MyDR := EventsDM.Current;
  2. {...more code ...}
  3. EventsDM.Current := MyDR;
the compiler generates calls to GetCurr and SetCurr transparently, without any more intervention from yourself.

Maybe you need to give a look-through to the Language Reference :)

ETA: I forgot! Regarding this:
Quote
If I try and tidy up the property/s to
    property SetCurrent : tDataResults write SetCurr;
    property GetCurrent : tDataResults read GetCurr;


The compile fails reporting: 'No member is provided to access property'.

In which line does it fails? I have just tested with this code:
Code: Pascal  [Select][+][-]
  1.   TForm1 = class(TForm)
  2.     {...standard controls & handlers here ...}
  3.   private
  4.     procedure SetWriteMe(AValue: String);
  5.     function GetReadMe: String;
  6.   public
  7.     property WriteMe: String write SetWriteMe;
  8.     property ReadMe: String read GetReadMe;
  9.     {There is "proper" code  for SetWriteMe and GetReadMe:
  10.      ShowMessage for WriteMe and InputBox for ReadMe}
  11.   end;
and it compiles (and works) alright. It may or may not make sense but read-only and write-only properties work ok.
Title: [Solved] Re: Class Property problems
Post by: iru on January 12, 2019, 09:41:25 am
Gentlefolk,

Thank you all for your comments.
I think that the comment and example code by lucamar covers things very well.

The code that failed to compile was 'EventsDM.SetCurrent(...);' where I was trying to use the property.

So I will redo a few things and battle on.

Thanks once again, Ian.
Title: Re: [Solved] Class Property problems
Post by: sash on January 12, 2019, 06:00:09 pm
Aside from unexplained naming and functional logic, formally you're trying to use write property as a procedure call, while it should be used as "L-Value", i.e. with assignment operator.
TinyPortal © 2005-2018