digitalmars.D.learn - Detecting a property setter?
- Rory McGuire (132/132) Jul 19 2010 boundary="----=_Part_27942_32606074.1279568935040"
- Simen kjaeraas (9/35) Jul 19 2010 For what it's worth, I would simply check if the property allows
- Philippe Sigaud (5/9) Jul 19 2010 In that case, for the second func, the one you call ReturnType on, how d...
- Jonathan M Davis (5/20) Jul 19 2010 I don't think that you're supposed to be able to have a getter property
- Rory McGuire (45/84) Jul 19 2010 Hehe good solution, never even crossed my mind.
- Rory McGuire (5/29) Jul 19 2010 I suppose it would be seen as a bug because it possibly circumvents the ...
- Rory McGuire (11/22) Jul 19 2010 Simen is using the fact that the compiler already has to figure out if
- Jonathan M Davis (9/12) Jul 19 2010 No, the problem is that you have _both_ a getter returning a ref and a s...
boundary="----=_Part_27942_32606074.1279568935040" ------=_Part_27942_32606074.1279568935040 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of "front": ============================== import std.traits; class Foo { uint num; property ref uint front() { return num; } property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) & FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) && ParameterTypeTuple!(func).length > 0 && ReturnType!(func).stringof != "void") ? true : false; } void main() { Foo foo; pragma(msg, hasSetter!(foo.front)); static if (isProperty!(foo.front)) { pragma(msg, "property"); } else { pragma(msg, "not a property"); } alias MemberFunctionsTuple!(Foo,"front") fronts; foreach (s; fronts) { pragma(msg, ReturnType!(s)); // this line just prints "uint" for both "front" properties! } } ============================ Is this a compiler bug? Or am I wrong again? Thanks Rory www.neonova.co.za: http://cf.neonova.co.za/9YXp View: https://mail1.clearformat.com/vcard.php?uid=11&pid=10 Beta Test Advert: http://fwd.clearformat.com/9YXn ------=_Part_27942_32606074.1279568935040 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: 7bit <html> <body> <div id="Headers"><div style="padding: 10px 0pt; background-color: rgb(37, 37, 37); color: rgb(255, 255, 255); font-size: 36px; font-family: Verdana,Arial,Helvetica,sans-serif,'Trebuchet MS','Times New Roman';"><img src="cid:logo.jpg 85027972.83801" title="Logo"></div></div><div id="Body_content"><div style="padding: 5px; font-family: Arial,Helvetica,sans-serif; font-size: 12px;"> Hi,<br /> <br /> Does anyone know how to detect if there is a setter for a property? The <br /> code below prints the same thing for both<br /> the setter and the getter of "front":<br /> <br /> ==============================<br /> import std.traits;<br /> <br /> class Foo {<br /> uint num;<br /> <br /> property ref uint front() {<br /> return num;<br /> }<br /> property void front(uint i) {<br /> num = i;<br /> }<br /> <br /> ref uint front2() {<br /> return num;<br /> }<br /> }<br /> <br /> template isProperty(alias func) if (isCallable!(func)) {<br /> enum isProperty = (functionAttributes!(func) & <br /> FunctionAttribute.PROPERTY)==0 ? false : true;<br /> }<br /> <br /> template hasSetter(alias func) if (isCallable!(func)) {<br /> enum hasSetter = (isProperty!(func) && ParameterTypeTuple!(func).length > <br /> 0 && ReturnType!(func).stringof != "void") ? true : false;<br /> }<br /> <br /> void main() {<br /> Foo foo;<br /> pragma(msg, hasSetter!(foo.front));<br /> <br /> static if (isProperty!(foo.front)) {<br /> pragma(msg, "property");<br /> } else {<br /> pragma(msg, "not a property");<br /> }<br /> <br /> alias MemberFunctionsTuple!(Foo,"front") fronts;<br /> foreach (s; fronts) {<br /> pragma(msg, ReturnType!(s)); // this line just prints "uint" for both <br /> "front" properties!<br /> }<br /> }<br /> ============================<br /> <br /> <br /> Is this a compiler bug? Or am I wrong again?<br /> <br /> Thanks<br /> Rory<br /> </div></div><div id="Signatures"><div style="padding: 3px; background-color: rgb(238, 235, 230); color: rgb(86, 80, 68); line-height: 15px; font-size: 10px; font-family: Verdana,Arial,Helvetica,sans-serif;"> <strong>Rory McGuire</strong><br> R&D<br><br> Tel : +27 (033) 386 7263<br> <br /> Cell : +27 (082) 856 3646<br /> <strong>Email</strong>: <a href="mailto:rmcguire neonova.co.za" style="font-size: 10px; font-family: Verdana,Arial,Helvetica,sans-serif; color: rgb(86, 80, 68);">rmcguire neonova.co.za</a><br> <strong>Website</strong>: <a href="http://cf.neonova.co.za/9YXp" style="font-size: 10px; font-family: Verdana,Arial,Helvetica,sans-serif; color: rgb(86, 80, 68);">www.neonova.co.za</a><br> <strong>VCard</strong>: <a href="https://mail1.clearformat.com/vcard.php?uid=11&pid=10" style="font-size: 10px; font-family: Verdana,Arial,Helvetica,sans-serif; color: rgb(86, 80, 68);">View</a><br> </div></div><div class="inline_ad"><a href="http://fwd.clearformat.com/9YXn" target="_blank"><img src="cid:ff2d54b.jpg 1163517217.14931" alt="Beta Test Advert" border="0" class="inline_img"/></a></div> <div style="font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; <div align="justify">This email and its attachments may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of NeoNova. If you are not the intended recipient of this email and its attachments, you must take no action based upon them, nor must you copy or show them to anyone. Please contact the sender if you believe you have received this email in error.</div> </div> </body> </html> ------=_Part_27942_32606074.1279568935040--
Jul 19 2010
Rory McGuire <rmcguire neonova.co.za> wrote:Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of "front": ============================== import std.traits; class Foo { uint num; property ref uint front() { return num; } property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) & FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) && ParameterTypeTuple!(func).lengthFor what it's worth, I would simply check if the property allows assignment. i.e.: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); } -- Simen0 && ReturnType!(func).stringof != "void") ? true : false; }
Jul 19 2010
On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas <simen.kjaras gmail.com>wrote:template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); }In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one? Philippe
Jul 19 2010
On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote:On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas <simen.kjaras gmail.com>wrote:I don't think that you're supposed to be able to have a getter property returning a ref at the same time that you have a setter property with the same name. It certainly sounds like it should be a bug in any case. - Jonathan M Davistemplate hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); }In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one? Philippe
Jul 19 2010
On Mon, 19 Jul 2010 22:06:14 +0200, Simen kjaeraas <simen.kjaras gmail.com> wrote:Rory McGuire <rmcguire neonova.co.za> wrote:Hehe good solution, never even crossed my mind. And it doesn't match ref return types such as the following signature. ref uint front() { return num; } My test code below: =================================== import std.traits; class Foo { uint num; property ref uint front() { return num; } /+ property void front(uint i) { num = i; }+/ ref uint front2() {return num;} } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) & FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); } void main() { Foo foo; pragma(msg, hasSetter!(foo.front)); // is the return type null (setter) static if (isProperty!(foo.front)) { pragma(msg, "property"); } else { pragma(msg, "not a property"); } alias MemberFunctionsTuple!(Foo,"front") fronts; foreach (s; fronts) { pragma(msg, hasSetter!(s)); } } ================================ Could be used in a GUI library for checking which properties of a class are editable and which are only for display. And tell you about it at compile time. Thanks!Does anyone know how to detect if there is a setter for a property? The code below prints the same thing for both the setter and the getter of "front": ============================== import std.traits; class Foo { uint num; property ref uint front() { return num; } property void front(uint i) { num = i; } ref uint front2() { return num; } } template isProperty(alias func) if (isCallable!(func)) { enum isProperty = (functionAttributes!(func) & FunctionAttribute.PROPERTY)==0 ? false : true; } template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = (isProperty!(func) && ParameterTypeTuple!(func).length > 0 && ReturnType!(func).stringof != "void") ? true : false; }For what it's worth, I would simply check if the property allows assignment. i.e.: template hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); }
Jul 19 2010
On Mon, 19 Jul 2010 23:25:01 +0200, Jonathan M Davis <jmdavisprog gmail.com> wrote:On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote:I suppose it would be seen as a bug because it possibly circumvents the getter/setter philosophy (If you return the internal value anyway).On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas <simen.kjaras gmail.com>wrote:I don't think that you're supposed to be able to have a getter property returning a ref at the same time that you have a setter property with the same name. It certainly sounds like it should be a bug in any case. - Jonathan M Davistemplate hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); }In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one? Philippe
Jul 19 2010
On Mon, 19 Jul 2010 22:42:51 +0200, Philippe Sigaud <philippe.sigaud gmail.com> wrote:On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas <simen.kjaras gmail.com> wrote:Simen is using the fact that the compiler already has to figure out if there is an overload that matches the requirements. So it ends up taking the only one that works. Since it seems to ignore the ref return type property, the property that takes an uint argument must have a higher precedence (gets checked if it works first). I wonder if its because Walter probably implemented function overloading before properties and ref return types. Hopefully its a language feature and not just a implementation side effect. -Rorytemplate hasSetter(alias func) if (isCallable!(func)) { enum hasSetter = isProperty!(func) && is( typeof( (){ func = ReturnType!(func).init; } ) ); }In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) andnot the void func() one?Philippe
Jul 19 2010
On Monday, July 19, 2010 14:37:22 Rory McGuire wrote:I suppose it would be seen as a bug because it possibly circumvents the getter/setter philosophy (If you return the internal value anyway).No, the problem is that you have _both_ a getter returning a ref and a setter. So, which does the compiler use? Returning a ref isn't a problem - phobos does it with ranges. Doing that, you basically user the getter for setting the property also. However, with both a getter returning a ref and a setter, then the compiler is going to have to choose which to use if you use the property as a setter. It's an ambiguity and thus shouldn't compile. If it does, then that's a bug. - Jonathan M Davis
Jul 19 2010