Jump to page: 1 2
Thread overview
Accessing Private Fields from Outside
May 17, 2011
Mehrdad
May 18, 2011
Robert Jacques
May 18, 2011
Mehrdad
May 18, 2011
Robert Jacques
May 18, 2011
Robert Jacques
May 18, 2011
Mehrdad
May 18, 2011
Adam D. Ruppe
May 18, 2011
Mehrdad
May 18, 2011
Adam D. Ruppe
May 18, 2011
Jacob Carlborg
May 18, 2011
gölgeliyele
May 18, 2011
Jacob Carlborg
May 17, 2011
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 18, 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 18, 2011
Check out the __traits(allMembers, TYPE) system:

http://dpldocs.info/traits
May 18, 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:
>
>> 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?
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?)
May 18, 2011
On 5/17/2011 5:18 PM, Adam D. Ruppe wrote:
> Check out the __traits(allMembers, TYPE) system:
>
> http://dpldocs.info/traits
Thanks, but traits doesn't really let me read or write to the variable though. :(
May 18, 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:
>> 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?
> 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.
May 18, 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 18, 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:
>
>> On 5/17/2011 5:13 PM, Robert Jacques wrote:
>>> 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?
>> 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.
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.
May 18, 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:
>
>> 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.

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:
>> 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.

Nope, getMember doesn't work, it gives me an inaccessible field error.
May 18, 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
« First   ‹ Prev
1 2