www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can attributes trigger functionality?

reply Psychological Cleanup <Help Saving.World> writes:
I'm having to create a lot of boiler plate code that creates 
"events" and corresponding properties(getter and setter).

I'm curious if I can simplify this without a string mixin.

If I create my own attribute like

 Event double foo();

and I write any code that will trigger when the event is used and 
add more code(such as the setter property and events that I need?

Obviously I could write some master template that scans 
everything, but that seems to be far too much over kill. A string 
mixin is probably my only option but is a bit ulgy for me.

Since attributes can be defined by structures it seems natural 
that we could put functionality in them that are triggered when 
used but I'm unsure if D has such capabilities.

Thanks.
Sep 05 2017
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 6 September 2017 at 02:43:20 UTC, Psychological 
Cleanup wrote:
 I'm having to create a lot of boiler plate code that creates 
 "events" and corresponding properties(getter and setter).

 I'm curious if I can simplify this without a string mixin.
You certainly don't need a string mixin, but you do need some code to react to the attribute. Here's one that generates a wrapper function on-demand: --- import std.stdio; import std.traits; class Test { cool void foo_() { writeln("cool function called"); } mixin CoolFunctions; } // our UDA enum cool; // adds the decorator implementation mixin template CoolFunctions() { template opDispatch(string name) if(hasUDA!(__traits(getMember, typeof(this), name ~ "_"), cool)) { auto opDispatch(Parameters!(__traits(getMember, typeof(this), name ~ "_")) params) { writeln("cool before"); scope(success) { writeln("cool after"); } return __traits(getMember, this, name ~ "_")(params); } } } void main() { auto test = new Test(); test.foo(); } ----- No string mixin (uses a mixin template instead), and not even a loop over the functions - it does them on-demand when used via opDispatch.
Sep 05 2017
prev sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 6 September 2017 at 02:43:20 UTC, Psychological 
Cleanup wrote:
 I'm having to create a lot of boiler plate code that creates 
 "events" and corresponding properties(getter and setter).

 I'm curious if I can simplify this without a string mixin.

 If I create my own attribute like

  Event double foo();

 and I write any code that will trigger when the event is used 
 and add more code(such as the setter property and events that I 
 need?

 Obviously I could write some master template that scans 
 everything, but that seems to be far too much over kill. A 
 string mixin is probably my only option but is a bit ulgy for 
 me.

 Since attributes can be defined by structures it seems natural 
 that we could put functionality in them that are triggered when 
 used but I'm unsure if D has such capabilities.

 Thanks.
User defined attributes (UDAs) are in and of themselves only (compile time) introspectable decoration [1] (they only carry information). If you want to trigger specific behaviour for things that are attributed with a UDA you indeed need to some custom written active component that introspects using `__traits(getAttributes, symbol) and generates injects generates the behaviour (e.g. using a string mixin as you noted). [1] https://dlang.org/spec/attribute.html#UserDefinedAttribute
Sep 05 2017