Recent

Author Topic: Custom Attributes for dummieś example  (Read 1666 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 10489
Custom Attributes for dummieś example
« on: August 02, 2019, 08:57:34 am »
Here's a complete example on how you use custom attributes ( create, decorate and retrieve )
It is a bit clearer than current documentation.
Code: Pascal  [Select][+][-]
  1. program testattributes;
  2. {
  3.   This is a simple example on how to use custom attributes.
  4.   The class uses a custom attribute to retrieve a date at
  5.   program start-up. This is just for the purpose of demo.
  6.   This demo's:
  7.   - Creation
  8.   - Decoration
  9.   - Retrieval
  10.  
  11.  
  12.   Enjoy,
  13.   Thaddy de Koning
  14. }
  15.    
  16. {$mode delphi}{$H+}{$M+}
  17. {$warn 5079 off} { turn warning experimental off }
  18. uses
  19.   sysutils, typinfo, rtti, classes;
  20.  
  21. type
  22.    {A custom attribute to decorate a class with a certain date }
  23.    ADateTimeAttribute = class(TCustomAttribute)
  24.    private
  25.      FArg:TDateTime;
  26.    public
  27.    { Just to show a Custom Attribute can have mutiple constructors }
  28.      constructor Create(const aArg: TDateTime);overload;
  29.      { We can use the predefined %DATE% compiler include
  30.        In the context of a custom attribute we need a
  31.        constant expression for the default parameter }
  32.      constructor Create(const aArg: String = {$I %DATE%});overload;
  33.     published
  34.      property Date:TDateTime read Farg;
  35.    end;
  36.  
  37.    { A datetime class that is decorated with our custom attribute     }
  38.    { Note you can leave out 'Attribute', the compiler resolves it     }
  39.    { [ADateTime(21237.0)] uses first constructor,displays my birthday }
  40.  
  41.    {This calls the second constructor }
  42.    [ADateTime]
  43.    TMyDateTimeClass = class
  44.    private
  45.      FDateTime:TDateTime;
  46.    public
  47.      constructor create;
  48.    published
  49.      [ADateTime]
  50.      property Day:TDateTime read FDatetime write FdateTime;
  51.    end;
  52.  
  53.    constructor ADateTimeAttribute.Create(const aArg: TDateTime);
  54.    begin
  55.      FArg := aArg;
  56.    end;
  57.  
  58.    constructor ADateTimeAttribute.Create(const aArg: string );
  59.    var
  60.      MySettings:Tformatsettings;
  61.    begin
  62.      { set up the date format according to how
  63.        the compiler formats %DATE% include }
  64.      MySettings :=DefaultFormatSettings;
  65.      MySettings.ShortDateFormat:='yyyymmdd';
  66.      MySettings.DateSeparator :='/';
  67.      { Now convert }
  68.      FArg := StrToDateTime(aArg, MySettings);
  69.    end;
  70.    
  71.    { We query the rtti to set the value }
  72.    constructor TMyDateTimeClass.Create;
  73.    var
  74.     Context : TRttiContext;
  75.     AType : TRttiType;
  76.     Attribute : TCustomAttribute;
  77.    begin
  78.      inherited;  
  79.      Context := TRttiContext.Create;
  80.      try
  81.        AType := Context.GetType(typeinfo(TMyDateTimeClass));
  82.        for Attribute in  AType.GetAttributes do
  83.          if Attribute is ADateTimeAttribute then
  84.            FDateTime := ADateTimeAttribute(Attribute).Date;
  85.      finally
  86.        Context.Free
  87.      end;    
  88.    end;
  89.  
  90.  
  91. var
  92.  Test:TMyDateTimeClass;      
  93. begin
  94.    Test := TMyDateTimeClass.Create;
  95.    try
  96.      writeln('Date is :',DateTimeToStr(Test.Day));
  97.   finally
  98.     test.free;
  99.   end;
  100. end.
« Last Edit: August 09, 2019, 08:24:37 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

devEric69

  • Sr. Member
  • ****
  • Posts: 331
Re: Custom Attributes for dummieś example
« Reply #1 on: August 30, 2019, 01:29:01 pm »
If I understand correctly, with FPC 3.2.0, there is a rtti unit, that contains TRttiContext (which should allows us to introspect with object-oriented RTTI, via oRttiContext.FindType, etc) as since Delphi 2010?
use: Linux 64 bits (Ubuntu 18.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

Thaddy

  • Hero Member
  • *****
  • Posts: 10489
Re: Custom Attributes for dummieś example
« Reply #2 on: August 30, 2019, 01:55:39 pm »
If I understand correctly, with FPC 3.2.0, there is a rtti unit, that contains TRttiContext (which should allows us to introspect with object-oriented RTTI, via oRttiContext.FindType, etc) as since Delphi 2010?
It is more trunk. RTTI is still being worked on and not totally complete. TRttiContext.FindType is not yet implemented. GetType is.
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

devEric69

  • Sr. Member
  • ****
  • Posts: 331
Re: Custom Attributes for dummieś example
« Reply #3 on: August 30, 2019, 02:32:35 pm »
All right.
I stay with my FPC version, and still keep my compilation defines in place....
Code: Pascal  [Select][+][-]
  1. {$IfDef TRTTI_CONTEXT}
  2. .../...
  3. {$EndIf}
...around some "old" Delphi  bits of source code.
use: Linux 64 bits (Ubuntu 18.04 LTS).
Lazarus version: 2.0.4 (svn revision: 62502M) compiled with fpc 3.0.4 - fpDebug \ Dwarf3.

mb

  • New Member
  • *
  • Posts: 10
Re: Custom Attributes for dummieś example
« Reply #4 on: May 15, 2020, 01:14:49 am »
I`ve tried this, but the class TCustomAttribute is not found anywhere ... I am newbee to Lazarus, so did I miss something? rtti is included, but even inside this unit shows no class of that type, rtti does not contain it.
I also copied the original code from documentation, but even with that copy it wont find this class.
I guess its some abstract type.
« Last Edit: May 15, 2020, 01:20:51 am by mb »

Bi0T1N

  • Jr. Member
  • **
  • Posts: 50
Re: Custom Attributes for dummieś example
« Reply #5 on: May 15, 2020, 03:04:11 am »
I`ve tried this, but the class TCustomAttribute is not found anywhere ... I am newbee to Lazarus, so did I miss something? rtti is included, but even inside this unit shows no class of that type, rtti does not contain it.
I also copied the original code from documentation, but even with that copy it wont find this class.
I guess its some abstract type.
It is only supported in FPC 3.3.1 (trunk) and requires the modeswitch PrefixedAttributes if mode is not Delphi or DelphiUnicode.

mb

  • New Member
  • *
  • Posts: 10
Re: Custom Attributes for dummieś example
« Reply #6 on: May 15, 2020, 09:45:01 am »
Thank you very much!

Ive already installed some 3.3.1 build and also included the prefixedattributes switch in my code. Rtti was working now, but the TCustomAttribute-Class was still not found.
Now Ive did some other search about trunk versions and came upon fpcupdeluxe. With that it is working now, class is found!

I am wondering, some comments about custom attributes are done back in 2012 and it is still only experimental.

What would be a different approach instead of using those attributes in Lazarus? C# uses them a lot and they give you great capabilities.
Of course I can do some dictionary which returns some attributes-classes, but that is not very optimal.

Bi0T1N

  • Jr. Member
  • **
  • Posts: 50
Re: Custom Attributes for dummieś example
« Reply #7 on: May 15, 2020, 01:05:09 pm »
Thank you very much!

Ive already installed some 3.3.1 build and also included the prefixedattributes switch in my code. Rtti was working now, but the TCustomAttribute-Class was still not found.
Now Ive did some other search about trunk versions and came upon fpcupdeluxe. With that it is working now, class is found!
You probably had a very old version of FPC trunk so it's very good that you found fpcupdeluxe - a really useful tool. ;D

I am wondering, some comments about custom attributes are done back in 2012 and it is still only experimental.

What would be a different approach instead of using those attributes in Lazarus? C# uses them a lot and they give you great capabilities.
Of course I can do some dictionary which returns some attributes-classes, but that is not very optimal.
I'm not sure about it but I think the custom attributes feature is not experimental but the underlying RTTI is. The unit name itself is unit Rtti experimental;. I assume its because not all the functionality (from Delphi?) is implemented yet and (breaking) changes could occur at any time.

Note: Removing
Code: Pascal  [Select][+][-]
  1. {$warn 5079 off} { turn warning experimental off }
from the code above shows
Code: Text  [Select][+][-]
  1. Warning: Unit "Rtti" is experimental
during compilation.
« Last Edit: May 15, 2020, 01:12:09 pm by Bi0T1N »

Thaddy

  • Hero Member
  • *****
  • Posts: 10489
Re: Custom Attributes for dummieś example
« Reply #8 on: May 15, 2020, 02:27:16 pm »
Ive already installed some 3.3.1 build
That alone is not very helpful. You need to build fpc trunk on a regular basis, for example when you see in the development https://svn.freepascal.org/cgi-bin/viewvc.cgi/?root=fpc that extended rtti has beem touched.
Trunk requires discipline, I build it almost daily. trunk on itself does not mean much, it is the revision that counts.
And my provided example works for months already.
This is to make clear that trunk is a moving target and can change features on any commit by the development team. (and on average that happens a lot!)
You should not only install a trunk version, but you also need to keep it current. fpcupdeluxe can do that for you but i would recommend to learn to build it yourself.
« Last Edit: May 15, 2020, 02:33:41 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

 

TinyPortal © 2005-2018