www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Accessing UDA of private field

reply Jacob Carlborg <doob me.com> writes:
I'm trying to adapt my serialization library, Orange, to use the new 
UDA's. Currently I have one template, NonSerialized, that I want to 
transfer to an UDA. This template works like:

class Foo
{
     int a;
     int b;

     mixin NonSerialized!(b);
}

When serializing Foo "b" will not be serialized. What the template does 
is adding a static field to the class, like this:

class Foo
{
     int a;
     int b;

     static enum __nonSerialized = ["b"];
}

Which I then can extract and use to exclude the fields from serialization.

This works fine to transfer to an UDA except in one case. That is when 
the field is not public. Orange will serialize all fields, regardless of 
the protection they have. I accomplish this by using the "tupleof" 
property of the class.

The problem is that to access a UDA attached to a field I need to pass a 
symbol to the __traits(getAttributes). With "tupleof" I can get the 
name, type and value of a field but I cannot get a symbol.

__traits(getMember) can be used to get the symbol but that will only 
work for public fields.

Does anyone have another solution? I had really hoped I could use UDA's 
in Orange.

https://github.com/jacob-carlborg/orange

-- 
/Jacob Carlborg
Jan 06 2013
next sibling parent d coder <dlang.coder gmail.com> writes:
--f46d044468e323e67004d2a19624
Content-Type: text/plain; charset=ISO-8859-1

Hello Jacob

I believe this would be possible using topleof once this
http://d.puremagic.com/issues/show_bug.cgi?id=9178 issue is taken care of.
Kindly vote it up. :-)


Regards
- Puneet

--f46d044468e323e67004d2a19624
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>Hello Jacob</div><div><br></div>I believe this would be possible using=
 topleof once this=A0<a href=3D"http://d.puremagic.com/issues/show_bug.cgi?=
id=3D9178">http://d.puremagic.com/issues/show_bug.cgi?id=3D9178</a> issue i=
s taken care of. Kindly vote it up. :-)<div>

<br></div><div><br></div><div>Regards</div><div>- Puneet</div><div><br></di=
v>

--f46d044468e323e67004d2a19624--
Jan 06 2013
prev sibling next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
--bcaec51b16d57143ee04d2a20d2b
Content-Type: text/plain; charset=UTF-8

 The problem is that to access a UDA attached to a field I need to pass a
 symbol to the __traits(getAttributes). With "tupleof" I can get the name,
 type and value of a field but I cannot get a symbol.

 __traits(getMember) can be used to get the symbol but that will only work
 for public fields.

You can use a string mixin: class Foo { int a; (3) private int b; } void main() { writeln(mixin("__traits(getAttributes, " ~ Foo.tupleof[1].stringof ~ ")")); // -> 3 } --bcaec51b16d57143ee04d2a20d2b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m= argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> The problem is that to access a UDA attached to a field I need to pass a sy= mbol to the __traits(getAttributes). With &quot;tupleof&quot; I can get the= name, type and value of a field but I cannot get a symbol.<br> <br> __traits(getMember) can be used to get the symbol but that will only work f= or public fields.<br></blockquote><div><br></div><div>You can use a string = mixin:</div><div><br></div><div>class Foo</div><div>{</div><div>=C2=A0 =C2= =A0 int a;</div> <div>=C2=A0 =C2=A0 (3) private int b;</div><div>}</div><div><br></div><div=
void main()</div><div>{</div><div>=C2=A0 =C2=A0 writeln(mixin(&quot;__trai=

gt; 3</div><div> }</div><div><br></div><div>=C2=A0</div></div> --bcaec51b16d57143ee04d2a20d2b--
Jan 06 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-06 18:29, Philippe Sigaud wrote:

 You can use a string mixin:

 class Foo
 {
      int a;
       (3) private int b;
 }

 void main()
 {
      writeln(mixin("__traits(getAttributes, " ~ Foo.tupleof[1].stringof
 ~ ")")); // -> 3
 }

Good thinking. It's not pretty but it works. Thanks. -- /Jacob Carlborg
Jan 06 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-01-06 23:33, Philippe Sigaud wrote:
     Good thinking. It's not pretty but it works. Thanks.


 Maybe it can be hidden inside a template?

Yeah, I'll see what I can do. -- /Jacob Carlborg
Jan 07 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-01-07 12:59, Tove wrote:

 in which context does private fail? I'm using something like this:

 struct my_struct
 {
 private:
     (1) int t1;
     (2) int t2;
     (3) int t3;
 }

 foreach(m; __traits(allMembers, my_struct))
    with(my_struct.init)
      pragma(msg, __traits(getAttributes, mixin(m)));

Using a mixin works. -- /Jacob Carlborg
Jan 07 2013
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
--14dae9340747b5cfd704d2a32262
Content-Type: text/plain; charset=ISO-8859-1

 You can use a string mixin:

 class Foo
 {
     int a;
      (3) private int b;
 }

 void main()
 {
     writeln(mixin("__traits(getAttributes, " ~ Foo.tupleof[1].stringof ~
 ")")); // -> 3
 }

Hmm.... This works only when main is in the same file (and therefor module) as Foo. Regards - Puneet --14dae9340747b5cfd704d2a32262 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m= argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D= "gmail_quote"><div>You can use a string mixin:</div><div><br></div><div>cla= ss Foo</div> <div>{</div><div>=A0 =A0 int a;</div> <div>=A0 =A0 (3) private int b;</div><div>}</div><div><br></div><div>void = main()</div><div>{</div><div>=A0 =A0 writeln(mixin(&quot;__traits(getAttrib= utes, &quot; ~ Foo.tupleof[1].stringof ~ &quot;)&quot;)); // -&gt; 3</div><= div> }</div><div><br></div><div>=A0</div></div></blockquote><div><br></div><div>= Hmm....</div><div><br></div><div>This works only when main is in the same f= ile (and therefor module) as Foo.</div><div><br></div><div>Regards</div> <div>- Puneet</div><div>=A0</div></div><br> --14dae9340747b5cfd704d2a32262--
Jan 06 2013
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--047d7b6777f271cfdd04d2a4266b
Content-Type: text/plain; charset=UTF-8

On Sun, Jan 6, 2013 at 7:46 PM, d coder <dlang.coder gmail.com> wrote:

 You can use a string mixin:
 class Foo
 {
     int a;
      (3) private int b;
 }

 void main()
 {
     writeln(mixin("__traits(getAttributes, " ~ Foo.tupleof[1].stringof ~
 ")")); // -> 3
 }

Hmm.... This works only when main is in the same file (and therefor module) as Foo.

interesting part is the mixin, the rest is just scaffolding to print a result. If Jacob adopts this solution, he can insert these mixins where he needs them. --047d7b6777f271cfdd04d2a4266b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Sun, Jan 6, 2013 at 7:46 PM, d coder = <span dir=3D"ltr">&lt;<a href=3D"mailto:dlang.coder gmail.com" target=3D"_b= lank">dlang.coder gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"g= mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l= eft:1ex"> <br><div class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gmail= _quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:= 1ex"><div class=3D"gmail_quote"><div>You can use a string mixin:</div><div>= <br></div> <div>class Foo</div> <div>{</div><div>=C2=A0 =C2=A0 int a;</div> <div>=C2=A0 =C2=A0 (3) private int b;</div><div>}</div><div><br></div><div=
void main()</div><div>{</div><div>=C2=A0 =C2=A0 writeln(mixin(&quot;__trai=

gt; 3</div><div> }</div><div><br></div><div>=C2=A0</div></div></blockquote><div><br></div></= div><div>Hmm....</div><div><br></div><div>This works only when main is in t= he same file (and therefor module) as Foo.</div><div><br></div></div></bloc= kquote> <div><br></div><div>Yes, but the OP question was to get the attributes in a= generic way. The interesting part is the mixin, the rest is just scaffoldi= ng to print a result.</div><div>If Jacob adopts this solution, he can inser= t these mixins where he needs them.</div> <div><br></div><div><br></div></div> --047d7b6777f271cfdd04d2a4266b--
Jan 06 2013
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--047d7bdc1be420b97004d2a64d07
Content-Type: text/plain; charset=UTF-8

 Good thinking. It's not pretty but it works. Thanks.

Maybe it can be hidden inside a template? --047d7bdc1be420b97004d2a64d07 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m= argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Good thinking. It&#39;s not pretty but it works. Thanks.</blockquote><div><= br></div><div>Maybe it can be hidden inside a template?=C2=A0</div></div> --047d7bdc1be420b97004d2a64d07--
Jan 06 2013
prev sibling next sibling parent "Tove" <tove fransson.se> writes:
On Monday, 7 January 2013 at 10:19:45 UTC, Jacob Carlborg wrote:
 On 2013-01-06 23:33, Philippe Sigaud wrote:
    Good thinking. It's not pretty but it works. Thanks.


 Maybe it can be hidden inside a template?

Yeah, I'll see what I can do.

in which context does private fail? I'm using something like this: struct my_struct { private: (1) int t1; (2) int t2; (3) int t3; } foreach(m; __traits(allMembers, my_struct)) with(my_struct.init) pragma(msg, __traits(getAttributes, mixin(m)));
Jan 07 2013
prev sibling next sibling parent "Tove" <tove fransson.se> writes:
On Monday, 7 January 2013 at 13:36:47 UTC, Jacob Carlborg wrote:
 On 2013-01-07 12:59, Tove wrote:

 in which context does private fail? I'm using something like 
 this:

 struct my_struct
 {
 private:
    (1) int t1;
    (2) int t2;
    (3) int t3;
 }

 foreach(m; __traits(allMembers, my_struct))
   with(my_struct.init)
     pragma(msg, __traits(getAttributes, mixin(m)));

Using a mixin works.

but this seems to work too? import std.traits; struct my_struct { private: (1) int t1; (2) int t2; (3) int t3; } void main() { foreach(m; __traits(allMembers, my_struct)) pragma(msg, __traits(getAttributes, __traits(getMember, my_struct, m))); }
Jan 07 2013
prev sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 7 January 2013 at 15:37:48 UTC, Tove wrote:
 but this seems to work too?

 import std.traits;

 struct my_struct
 {
 private:
    (1) int t1;
    (2) int t2;
    (3) int t3;
 }
 void main()
 {
   foreach(m; __traits(allMembers, my_struct))
     pragma(msg, __traits(getAttributes, __traits(getMember, 
 my_struct, m)));
 }

»private« means »accessible from this module« – are you running your tests with my_struct defined in a different module? David
Jan 07 2013