www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Getters/setters generator

reply Eugene Wissner <belka caraus.de> writes:
Hello,

we've just open sourced a small module ("accessors") that helps 
to generate getters and setters automatically:
https://github.com/funkwerk/accessors
http://code.dlang.org/packages/accessors

It takes advantage of the UDAs and mixins. A simple example would 
be:

import accessors;

class WithAccessors
{
      Read  Write
     private int num_;

     mixin(GenerateFieldAccessors);
}

It would generate 2 methods "num": one to set num_ and one to get 
its value. Of cause you can generate only  Read without  Write 
and vice versa. There are some more features, you can find the 
full documentation in the README.
"GenerateFieldAccessors" mixin should be added into each 
class/struct that wants to use auto generated accessors.
Dec 09 2016
next sibling parent reply Iakh <iaktakh gmail.com> writes:
On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner wrote:
 Hello,

 we've just open sourced a small module ("accessors") that helps 
 to generate getters and setters automatically:
 https://github.com/funkwerk/accessors
 http://code.dlang.org/packages/accessors

 It takes advantage of the UDAs and mixins. A simple example 
 would be:

 import accessors;

 class WithAccessors
 {
      Read  Write
     private int num_;

     mixin(GenerateFieldAccessors);
 }

 It would generate 2 methods "num": one to set num_ and one to 
 get its value. Of cause you can generate only  Read without 
  Write and vice versa. There are some more features, you can 
 find the full documentation in the README.
 "GenerateFieldAccessors" mixin should be added into each 
 class/struct that wants to use auto generated accessors.
Is there possibility to remove affixes in generated accessor names?
Dec 09 2016
parent reply Eugene Wissner <belka caraus.de> writes:
On Friday, 9 December 2016 at 12:37:58 UTC, Iakh wrote:
 Is there possibility to remove affixes in generated accessor 
 names?
No, there is no way to manipulate the accessor names. What affixes do you mean?
Dec 09 2016
parent reply Iakh <iaktakh gmail.com> writes:
On Friday, 9 December 2016 at 16:30:55 UTC, Eugene Wissner wrote:
 On Friday, 9 December 2016 at 12:37:58 UTC, Iakh wrote:
 Is there possibility to remove affixes in generated accessor 
 names?
No, there is no way to manipulate the accessor names. What affixes do you mean?
You can remove suffix "_" so "name_" becomes "name". But I like to see genarated accessors "name" for field "m_name"
Dec 10 2016
parent Eugene Wissner <belka caraus.de> writes:
On Saturday, 10 December 2016 at 16:37:53 UTC, Iakh wrote:
 On Friday, 9 December 2016 at 16:30:55 UTC, Eugene Wissner 
 wrote:
 On Friday, 9 December 2016 at 12:37:58 UTC, Iakh wrote:
 Is there possibility to remove affixes in generated accessor 
 names?
No, there is no way to manipulate the accessor names. What affixes do you mean?
You can remove suffix "_" so "name_" becomes "name". But I like to see genarated accessors "name" for field "m_name"
no, it isn't possible. we just hard coded the most simple and the most "d-style" convention.
Dec 11 2016
prev sibling next sibling parent Iakh <iaktakh gmail.com> writes:
mixin template GenerateFieldAccessorMethods()
{
     static enum GenerateFieldAccessorMethods()
     {
         string result = "";
         return result;
     }
}

Strange syntax
Dec 09 2016
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/9/16 5:27 AM, Eugene Wissner wrote:
 Hello,

 we've just open sourced a small module ("accessors") that helps to
 generate getters and setters automatically:
 https://github.com/funkwerk/accessors
 http://code.dlang.org/packages/accessors

 It takes advantage of the UDAs and mixins. A simple example would be:

 import accessors;

 class WithAccessors
 {
      Read  Write
     private int num_;

     mixin(GenerateFieldAccessors);
 }

 It would generate 2 methods "num": one to set num_ and one to get its
 value. Of cause you can generate only  Read without  Write and vice
 versa. There are some more features, you can find the full documentation
 in the README.
 "GenerateFieldAccessors" mixin should be added into each class/struct
 that wants to use auto generated accessors.
Love it, and was toying with similar ideas too. One good extension is to add a predicate to the setter, which guards the assignment. -- Andrei
Dec 09 2016
parent reply Eugene Wissner <belka caraus.de> writes:
On Friday, 9 December 2016 at 18:53:55 UTC, Andrei Alexandrescu 
wrote:
 Love it, and was toying with similar ideas too. One good 
 extension is to add a predicate to the setter, which guards the 
 assignment. -- Andrei
What kind of predicate do you mean? Can you give an example please?
Jan 16
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Tuesday, 17 January 2017 at 06:26:35 UTC, Eugene Wissner wrote:
 On Friday, 9 December 2016 at 18:53:55 UTC, Andrei Alexandrescu 
 wrote:
 Love it, and was toying with similar ideas too. One good 
 extension is to add a predicate to the setter, which guards 
 the assignment. -- Andrei
What kind of predicate do you mean? Can you give an example please?
setValue(uint _under24) { assert(_under24 < 24); under24 = _under24; }
Jan 16
parent reply Eugene Wissner <belka caraus.de> writes:
On Tuesday, 17 January 2017 at 07:06:05 UTC, Stefan Koch wrote:
 On Tuesday, 17 January 2017 at 06:26:35 UTC, Eugene Wissner 
 wrote:
 On Friday, 9 December 2016 at 18:53:55 UTC, Andrei 
 Alexandrescu wrote:
 Love it, and was toying with similar ideas too. One good 
 extension is to add a predicate to the setter, which guards 
 the assignment. -- Andrei
What kind of predicate do you mean? Can you give an example please?
setValue(uint _under24) { assert(_under24 < 24); under24 = _under24; }
Ah, well thanks. I don't think it makes much sense since it would be easier to write a complete setter if the user needs extra checks. Accessors are there only for the generation of the standard methods, that just get or set some object property.
Jan 16
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/17 9:32 AM, Eugene Wissner wrote:
 Ah, well thanks. I don't think it makes much sense since it would be
 easier to write a complete setter if the user needs extra checks.
 Accessors are there only for the generation of the standard methods,
 that just get or set some object property.
Hmmm... that's a bit of a bummer because it helps only the degenerate case (accessors are there as placeholders for future extensions, and otherwise offer no protection whatsoever compared to a public value). The question would be then what would be use cases for the accessors. Predicated setters are not just a random thing one might want out of many possibilities, it's a frequent pattern. -- Andrei
Jan 17
parent reply Mark <smarksc gmail.com> writes:
On Tuesday, 17 January 2017 at 09:17:56 UTC, Andrei Alexandrescu 
wrote:
 On 1/17/17 9:32 AM, Eugene Wissner wrote:
 Ah, well thanks. I don't think it makes much sense since it 
 would be
 easier to write a complete setter if the user needs extra 
 checks.
 Accessors are there only for the generation of the standard 
 methods,
 that just get or set some object property.
Hmmm... that's a bit of a bummer because it helps only the degenerate case (accessors are there as placeholders for future extensions, and otherwise offer no protection whatsoever compared to a public value). The question would be then what would be use cases for the accessors. Predicated setters are not just a random thing one might want out of many possibilities, it's a frequent pattern. -- Andrei
Given that D supports class invariants, is there a real need for predicated setters?
Jan 17
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/17 12:08 PM, Mark wrote:
 On Tuesday, 17 January 2017 at 09:17:56 UTC, Andrei Alexandrescu wrote:
 On 1/17/17 9:32 AM, Eugene Wissner wrote:
 Ah, well thanks. I don't think it makes much sense since it would be
 easier to write a complete setter if the user needs extra checks.
 Accessors are there only for the generation of the standard methods,
 that just get or set some object property.
Hmmm... that's a bit of a bummer because it helps only the degenerate case (accessors are there as placeholders for future extensions, and otherwise offer no protection whatsoever compared to a public value). The question would be then what would be use cases for the accessors. Predicated setters are not just a random thing one might want out of many possibilities, it's a frequent pattern. -- Andrei
Given that D supports class invariants, is there a real need for predicated setters?
The invariant is evaluated after the setter has taken place, i.e. after the object has been corrupted. The setter guard prevents corruption from happening. -- Andrei
Jan 17
parent reply Mark <smarksc gmail.com> writes:
On Tuesday, 17 January 2017 at 15:59:26 UTC, Andrei Alexandrescu 
wrote:
 On 1/17/17 12:08 PM, Mark wrote:
 On Tuesday, 17 January 2017 at 09:17:56 UTC, Andrei 
 Alexandrescu wrote:
 On 1/17/17 9:32 AM, Eugene Wissner wrote:
 Ah, well thanks. I don't think it makes much sense since it 
 would be
 easier to write a complete setter if the user needs extra 
 checks.
 Accessors are there only for the generation of the standard 
 methods,
 that just get or set some object property.
Hmmm... that's a bit of a bummer because it helps only the degenerate case (accessors are there as placeholders for future extensions, and otherwise offer no protection whatsoever compared to a public value). The question would be then what would be use cases for the accessors. Predicated setters are not just a random thing one might want out of many possibilities, it's a frequent pattern. -- Andrei
Given that D supports class invariants, is there a real need for predicated setters?
The invariant is evaluated after the setter has taken place, i.e. after the object has been corrupted. The setter guard prevents corruption from happening. -- Andrei
I see. Is there a way to call invariant() of a class/struct directly? That would obviate the need for a particular predicate (copy the class state, run the setter, check if invariants are satisfied and restore previous state if they aren't).
Jan 18
next sibling parent Nemanja Boric <4burgos gmail.com> writes:
On Wednesday, 18 January 2017 at 15:29:43 UTC, Mark wrote:
 On Tuesday, 17 January 2017 at 15:59:26 UTC, Andrei 
 Alexandrescu wrote:
 On 1/17/17 12:08 PM, Mark wrote:
 On Tuesday, 17 January 2017 at 09:17:56 UTC, Andrei 
 Alexandrescu wrote:
 [...]
Given that D supports class invariants, is there a real need for predicated setters?
The invariant is evaluated after the setter has taken place, i.e. after the object has been corrupted. The setter guard prevents corruption from happening. -- Andrei
I see. Is there a way to call invariant() of a class/struct directly? That would obviate the need for a particular predicate (copy the class state, run the setter, check if invariants are satisfied and restore previous state if they aren't).
You can call invariant directly with `assert(this);` IIRC.
Jan 18
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/17 5:29 PM, Mark wrote:
 I see. Is there a way to call invariant() of a class/struct directly?
 That would obviate the need for a particular predicate (copy the class
 state, run the setter, check if invariants are satisfied and restore
 previous state if they aren't).
It seems painfully obvious the right way is a guarded assignment and anything else would be a more or less painful workaround. -- Andrei
Jan 18
parent Mark <smarksc gmail.com> writes:
On Wednesday, 18 January 2017 at 21:57:42 UTC, Andrei 
Alexandrescu wrote:
 On 1/18/17 5:29 PM, Mark wrote:
 I see. Is there a way to call invariant() of a class/struct 
 directly?
 That would obviate the need for a particular predicate (copy 
 the class
 state, run the setter, check if invariants are satisfied and 
 restore
 previous state if they aren't).
It seems painfully obvious the right way is a guarded assignment and anything else would be a more or less painful workaround. -- Andrei
I agree. I'm just a bit unsettled by the slight code duplication that would ensue.
Jan 19
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/17 8:26 AM, Eugene Wissner wrote:
 On Friday, 9 December 2016 at 18:53:55 UTC, Andrei Alexandrescu wrote:
 Love it, and was toying with similar ideas too. One good extension is
 to add a predicate to the setter, which guards the assignment. -- Andrei
What kind of predicate do you mean? Can you give an example please?
Say you have a property "percent". The setter should do an enforce(value
= 0 && value <= 100) before the assignment. -- Andrei
Jan 17
prev sibling next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner wrote:
 Hello,

 we've just open sourced a small module ("accessors") that helps 
 to generate getters and setters automatically:
 https://github.com/funkwerk/accessors
 http://code.dlang.org/packages/accessors

 It takes advantage of the UDAs and mixins. A simple example 
 would be:

 import accessors;

 class WithAccessors
 {
      Read  Write
     private int num_;

     mixin(GenerateFieldAccessors);
 }

 It would generate 2 methods "num": one to set num_ and one to 
 get its value. Of cause you can generate only  Read without 
  Write and vice versa. There are some more features, you can 
 find the full documentation in the README.
 "GenerateFieldAccessors" mixin should be added into each 
 class/struct that wants to use auto generated accessors.
Oh my this is going to be a compiletime hog if used excessively. Due the use of fqn.
Dec 09 2016
prev sibling next sibling parent reply Mike Bierlee <m.bierlee lostmoment.com> writes:
On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner wrote:
 It would generate 2 methods "num": one to set num_ and one to 
 get its value.
It would be great if you could generate properties instead. I like the more natural way of accessing those instead of getters/setters.
Dec 10 2016
parent reply Mike Parker <aldacron gmail.com> writes:
On Saturday, 10 December 2016 at 20:25:05 UTC, Mike Bierlee wrote:
 On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner 
 wrote:
 It would generate 2 methods "num": one to set num_ and one to 
 get its value.
It would be great if you could generate properties instead. I like the more natural way of accessing those instead of getters/setters.
What are properties if not "getters" and "setters"? From the original post: "It would generate 2 methods "num": one to set num_ and one to get its value." Two methods named "num". No "get" or "set" in sight.
Dec 10 2016
parent reply Mike Bierlee <m.bierlee lostmoment.com> writes:
On Sunday, 11 December 2016 at 02:17:18 UTC, Mike Parker wrote:
 On Saturday, 10 December 2016 at 20:25:05 UTC, Mike Bierlee 
 wrote:
 On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner 
 wrote:
 It would generate 2 methods "num": one to set num_ and one to 
 get its value.
It would be great if you could generate properties instead. I like the more natural way of accessing those instead of getters/setters.
What are properties if not "getters" and "setters"? From the original post: "It would generate 2 methods "num": one to set num_ and one to get its value." Two methods named "num". No "get" or "set" in sight.
I was under the impression that you could only access methods as if they were fields using the property attribute. After carefully reading the documentation I see this is not the case (UFCS does this). Still there are some added benefits from using property to completely threat them as fields. It would be nice if you could add property to the generated getters/setters.
Dec 10 2016
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 11 December 2016 at 03:15:55 UTC, Mike Bierlee wrote:

 I was under the impression that you could only access methods 
 as if they were fields using the  property attribute. After 
 carefully reading the documentation I see this is not the case 
 (UFCS does this). Still there are some added benefits from 
 using  property to completely threat them as fields. It would 
 be nice if you could add  property to the generated 
 getters/setters.
Right, any no-arg function can be called without parentheses, and single-arg functions can be called as 'func = foo'. At this point, I don't think think property is ever going to be fixed to work as originally intended (and digging through the newsgroups will turn up several discussions on why, if you're interested). I don't bother with it anymore myself. DUB used to compile with it enabled by default, but no longer.
Dec 10 2016
parent Kapps <opantm2+spam gmail.com> writes:
On Sunday, 11 December 2016 at 06:55:22 UTC, Mike Parker wrote:
 On Sunday, 11 December 2016 at 03:15:55 UTC, Mike Bierlee wrote:

 I was under the impression that you could only access methods 
 as if they were fields using the  property attribute. After 
 carefully reading the documentation I see this is not the case 
 (UFCS does this). Still there are some added benefits from 
 using  property to completely threat them as fields. It would 
 be nice if you could add  property to the generated 
 getters/setters.
Right, any no-arg function can be called without parentheses, and single-arg functions can be called as 'func = foo'. At this point, I don't think think property is ever going to be fixed to work as origiInally intended (and digging through the newsgroups will turn up several discussions on why, if you're interested). I don't bother with it anymore myself. DUB used to compile with it enabled by default, but no longer.
I use it for intent. And I think it might affect overload sets? For example in my reflection library, I have a getValue function that returns metadata for a field or property, while getMethod would return it for just any old method.
Dec 13 2016
prev sibling next sibling parent Eugene Wissner <belka caraus.de> writes:
On Sunday, 11 December 2016 at 03:15:55 UTC, Mike Bierlee wrote:
 On Sunday, 11 December 2016 at 02:17:18 UTC, Mike Parker wrote:
 On Saturday, 10 December 2016 at 20:25:05 UTC, Mike Bierlee 
 wrote:
 On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner 
 wrote:
 It would generate 2 methods "num": one to set num_ and one 
 to get its value.
It would be great if you could generate properties instead. I like the more natural way of accessing those instead of getters/setters.
What are properties if not "getters" and "setters"? From the original post: "It would generate 2 methods "num": one to set num_ and one to get its value." Two methods named "num". No "get" or "set" in sight.
I was under the impression that you could only access methods as if they were fields using the property attribute. After carefully reading the documentation I see this is not the case (UFCS does this). Still there are some added benefits from using property to completely threat them as fields. It would be nice if you could add property to the generated getters/setters.
Yeah, I see, property seems to bring some additional features. Will think about it. Thanks.
Dec 11 2016
prev sibling parent Eugene Wissner <belka caraus.de> writes:
On Sunday, 11 December 2016 at 03:15:55 UTC, Mike Bierlee wrote:
 I was under the impression that you could only access methods 
 as if they were fields using the  property attribute. After 
 carefully reading the documentation I see this is not the case 
 (UFCS does this). Still there are some added benefits from 
 using  property to completely threat them as fields. It would 
 be nice if you could add  property to the generated 
 getters/setters.
Here is the pull request to add property to the generated methods: https://github.com/funkwerk/accessors/pull/4
Dec 14 2016
prev sibling parent Eugene Wissner <belka caraus.de> writes:
On Friday, 9 December 2016 at 10:27:05 UTC, Eugene Wissner wrote:
 Hello,

 we've just open sourced a small module ("accessors") that helps 
 to generate getters and setters automatically:
 https://github.com/funkwerk/accessors
 http://code.dlang.org/packages/accessors

 It takes advantage of the UDAs and mixins. A simple example 
 would be:

 import accessors;

 class WithAccessors
 {
      Read  Write
     private int num_;

     mixin(GenerateFieldAccessors);
 }

 It would generate 2 methods "num": one to set num_ and one to 
 get its value. Of cause you can generate only  Read without 
  Write and vice versa. There are some more features, you can 
 find the full documentation in the README.
 "GenerateFieldAccessors" mixin should be added into each 
 class/struct that wants to use auto generated accessors.
We just released the next version of the accessors: v1.1.0 - One problem with inheritance was fixed. - And the generated accessors are always properties know.
Jan 16