digitalmars.D - Accessing Private Fields from Outside
- Mehrdad (4/4) May 17 2011 Is there any (hacky) way of accessing a private field from outside a
- Robert Jacques (20/24) May 17 2011 The short answer:
- Mehrdad (7/34) May 17 2011 T.tupleof has a problem though: It doesn't seem to let me actually
- Robert Jacques (5/43) May 17 2011 I actually do both (name and value) in the above example.
- Robert Jacques (4/50) May 17 2011 P.S. In fact, since foreach(i,ref v;value.tupleof) won't compile, you ha...
- Mehrdad (7/29) May 17 2011 Hm, my bad. Seems like the newest version of DMD allows this, though I
- Adam D. Ruppe (2/2) May 17 2011 Check out the __traits(allMembers, TYPE) system:
- Mehrdad (3/5) May 17 2011 Thanks, but traits doesn't really let me read or write to the variable
- Adam D. Ruppe (6/8) May 17 2011 Use getMember there.
- Jacob Carlborg (8/12) May 18 2011 You can have a look at my serialization library, Orange:
- =?ISO-8859-1?Q?g=F6lgeliyele?= (9/14) May 18 2011 This is interesting. The list of limitations seem quite minimal. You
- Jacob Carlborg (17/34) May 18 2011 Don't know if they're actually bugs, more limitations. You would need
Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(
May 17 2011
On Tue, 17 May 2011 19:47:29 -0400, Mehrdad <wfunction hotmail.com> wrote:Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(The short answer: T.tupleof works for anything that you have the source to, but doesn't support polymorphism out of the box. The long answer (from my json library): static Value from(T)(T value) { static if(is(T == class) ) if( value is null ) return Value(Null.init); //... static if(is(T == struct) || is(T == class)) { Value[string] result; foreach(i,v;value.tupleof) { result[value.tupleof[i].stringof["value.".length..$]] = from(v); } return Value( result ); } //.. } P.S. Are you marshaling to/from an open format or something proprietary?
May 17 2011
On 5/17/2011 5:13 PM, Robert Jacques wrote:On Tue, 17 May 2011 19:47:29 -0400, Mehrdad <wfunction hotmail.com> wrote:T.tupleof has a problem though: It doesn't seem to let me actually access the value; it just give me a tuple I can't do anything with. Your example only gets the name of the field, but you never actually seem to access it. (P.S.: I'm trying to marshal from/to Windows data structures, so I guess it's kinda both?)Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(The short answer: T.tupleof works for anything that you have the source to, but doesn't support polymorphism out of the box. The long answer (from my json library): static Value from(T)(T value) { static if(is(T == class) ) if( value is null ) return Value(Null.init); //... static if(is(T == struct) || is(T == class)) { Value[string] result; foreach(i,v;value.tupleof) { result[value.tupleof[i].stringof["value.".length..$]] = from(v); } return Value( result ); } //.. } P.S. Are you marshaling to/from an open format or something proprietary?
May 17 2011
On Tue, 17 May 2011 20:44:24 -0400, Mehrdad <wfunction hotmail.com> wrote:On 5/17/2011 5:13 PM, Robert Jacques wrote:I actually do both (name and value) in the above example. Name: value.tupleof[i].stringof["value.".length..$] Value: v You can also use value.tupleof[i] if all you want is to set a field.On Tue, 17 May 2011 19:47:29 -0400, Mehrdad <wfunction hotmail.com> wrote:T.tupleof has a problem though: It doesn't seem to let me actually access the value; it just give me a tuple I can't do anything with. Your example only gets the name of the field, but you never actually seem to access it. (P.S.: I'm trying to marshal from/to Windows data structures, so I guess it's kinda both?)Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(The short answer: T.tupleof works for anything that you have the source to, but doesn't support polymorphism out of the box. The long answer (from my json library): static Value from(T)(T value) { static if(is(T == class) ) if( value is null ) return Value(Null.init); //... static if(is(T == struct) || is(T == class)) { Value[string] result; foreach(i,v;value.tupleof) { result[value.tupleof[i].stringof["value.".length..$]] = from(v); } return Value( result ); } //.. } P.S. Are you marshaling to/from an open format or something proprietary?
May 17 2011
On Tue, 17 May 2011 20:52:02 -0400, Robert Jacques <sandford jhu.edu> wrote:On Tue, 17 May 2011 20:44:24 -0400, Mehrdad <wfunction hotmail.com> wrote:P.S. In fact, since foreach(i,ref v;value.tupleof) won't compile, you have to use value.tupleof[i] to assign to a field.On 5/17/2011 5:13 PM, Robert Jacques wrote:I actually do both (name and value) in the above example. Name: value.tupleof[i].stringof["value.".length..$] Value: v You can also use value.tupleof[i] if all you want is to set a field.On Tue, 17 May 2011 19:47:29 -0400, Mehrdad <wfunction hotmail.com> wrote:T.tupleof has a problem though: It doesn't seem to let me actually access the value; it just give me a tuple I can't do anything with. Your example only gets the name of the field, but you never actually seem to access it. (P.S.: I'm trying to marshal from/to Windows data structures, so I guess it's kinda both?)Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(The short answer: T.tupleof works for anything that you have the source to, but doesn't support polymorphism out of the box. The long answer (from my json library): static Value from(T)(T value) { static if(is(T == class) ) if( value is null ) return Value(Null.init); //... static if(is(T == struct) || is(T == class)) { Value[string] result; foreach(i,v;value.tupleof) { result[value.tupleof[i].stringof["value.".length..$]] = from(v); } return Value( result ); } //.. } P.S. Are you marshaling to/from an open format or something proprietary?
May 17 2011
On 5/17/2011 5:52 PM, Robert Jacques wrote:On Tue, 17 May 2011 20:44:24 -0400, Mehrdad <wfunction hotmail.com> wrote:Hm, my bad. Seems like the newest version of DMD allows this, though I could swear I couldn't do that before (it would say the member is inaccessible). :-) (And yeah, I already noticed that thing about foreach(ref), thanks.) On 5/17/2011 5:56 PM, Adam D. Ruppe wrote:On 5/17/2011 5:13 PM, Robert Jacques wrote: T.tupleof has a problem though: It doesn't seem to let me actually access the value; it just give me a tuple I can't do anything with. Your example only gets the name of the field, but you never actually seem to access it. (P.S.: I'm trying to marshal from/to Windows data structures, so I guess it's kinda both?)I actually do both (name and value) in the above example. Name: value.tupleof[i].stringof["value.".length..$] Value: v You can also use value.tupleof[i] if all you want is to set a field.Nope, getMember doesn't work, it gives me an inaccessible field error.Thanks, but traits doesn't really let me read or write to the variable though. :(Use getMember there. foreach(member; __traits(allMembers, TYPE)) __traits(getMember, instance_of_type, member) = something; tupleof is probably better for this though, since it only includes actual data members; it excludes methods. You can write to tupleof by using an index.
May 17 2011
Check out the __traits(allMembers, TYPE) system: http://dpldocs.info/traits
May 17 2011
On 5/17/2011 5:18 PM, Adam D. Ruppe wrote:Check out the __traits(allMembers, TYPE) system: http://dpldocs.info/traitsThanks, but traits doesn't really let me read or write to the variable though. :(
May 17 2011
Thanks, but traits doesn't really let me read or write to the variable though. :(Use getMember there. foreach(member; __traits(allMembers, TYPE)) __traits(getMember, instance_of_type, member) = something; tupleof is probably better for this though, since it only includes actual data members; it excludes methods. You can write to tupleof by using an index.
May 17 2011
On 2011-05-18 01:47, Mehrdad wrote:Is there any (hacky) way of accessing a private field from outside a data type? (The equivalent of reflection in managed languages.) I'm trying to write a piece of marshaling code that needs access to a data type's fields, but can't access them because it's not allowed to. :(You can have a look at my serialization library, Orange: http://www.dsource.org/projects/orange I don't think it works with the latest compilers but you have have a look at the source: http://www.dsource.org/projects/orange/browser/orange/util/Reflection.d#L277 -- /Jacob Carlborg
May 18 2011
On 5/18/11 5:30 AM, Jacob Carlborg wrote:You can have a look at my serialization library, Orange: http://www.dsource.org/projects/orange I don't think it works with the latest compilers but you have have a look at the source: http://www.dsource.org/projects/orange/browser/orange/util/Reflection.d#L277This is interesting. The list of limitations seem quite minimal. You mention: 'Due to several bugs in the compiler even the D2 version requires you to register a serializer when serializing through base class references' Is there a list of these bugs? Would resolving these bugs remove the need for registration functions? Would it be possible to have a library like this in Phobos? Are there any performance gotchas?
May 18 2011
On 2011-05-18 12:32, gölgeliyele wrote:On 5/18/11 5:30 AM, Jacob Carlborg wrote:Don't know if they're actually bugs, more limitations. You would need more reflection capabilities. Better support for getting and setting instance variables via reflection. Using ClassInfo.getMembers you can get the members of a class, but you can get or set the values. In addition to that there are also two bugs related to getMembers: * http://d.puremagic.com/issues/show_bug.cgi?id=2844 * And one I never can find, getMembers always returns an empty array If I understand ClassInfo.getMembers correctly, and when it's implementation is correct, you should be able to get the members of a subclass trough a base class reference.You can have a look at my serialization library, Orange: http://www.dsource.org/projects/orange I don't think it works with the latest compilers but you have have a look at the source: http://www.dsource.org/projects/orange/browser/orange/util/Reflection.d#L277This is interesting. The list of limitations seem quite minimal. You mention: 'Due to several bugs in the compiler even the D2 version requires you to register a serializer when serializing through base class references' Is there a list of these bugs? Would resolving these bugs remove the need for registration functions?Would it be possible to have a library like this in Phobos? Are there any performance gotchas?It would be possible, yes. The current implementation is not the best, I'm in the middle of a complete rewrite. The current implementation adds instance variables to classes/structs but these should be static. -- /Jacob Carlborg
May 18 2011