Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
June 21, 2013 allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
module test; void test() { foreach (member; __traits(allMembers, Client)) { pragma(msg, member); // Prints all members fine, including "value" } // This line fails static if(__traits(getProtection, __traits(getMember, TestClass, "value")) == "public") { pragma(msg, "value is public"); } else { pragma(msg, "value is not public"); } } module testclass; class TestClass { private: int value; } When using the allMembers trait, the private "value" member of TestClass is included, but when trying to retrieve that member using the getMember trait, it fails to compile with test.d(13): Error: class main.TestClass member value is not accessible Is that intended behavior or a bug? I can't see why the getMember trait should not be able to retrieve private members when allMembers trait is |
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin | On 2013-06-21 15:04, Martin wrote: > module test; > > void test() > { > > > foreach (member; __traits(allMembers, Client)) > { > pragma(msg, member); // Prints all members fine, including "value" > } > > // This line fails > static if(__traits(getProtection, __traits(getMember, TestClass, > "value")) == "public") > { > pragma(msg, "value is public"); > } > else > { > pragma(msg, "value is not public"); > } > > } > > module testclass; > > class TestClass > { > private: > int value; > } > > When using the allMembers trait, the private "value" member of TestClass > is included, but when trying to retrieve that member using the getMember > trait, it fails to compile with test.d(13): Error: class main.TestClass > member value is not accessible > > Is that intended behavior or a bug? I can't see why the getMember trait > should not be able to retrieve private members when allMembers trait is Can you use a string instead of getMember? -- /Jacob Carlborg |
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
> On 2013-06-21 15:04, Martin wrote:
>> module test;
>>
>> void test()
>> {
>>
>>
>> foreach (member; __traits(allMembers, Client))
>> {
>> pragma(msg, member); // Prints all members fine, including "value"
>> }
>>
>> // This line fails
>> static if(__traits(getProtection, __traits(getMember, TestClass,
>> "value")) == "public")
>> {
>> pragma(msg, "value is public");
>> }
>> else
>> {
>> pragma(msg, "value is not public");
>> }
>>
>> }
>>
>> module testclass;
>>
>> class TestClass
>> {
>> private:
>> int value;
>> }
>>
>> When using the allMembers trait, the private "value" member of TestClass
>> is included, but when trying to retrieve that member using the getMember
>> trait, it fails to compile with test.d(13): Error: class main.TestClass
>> member value is not accessible
>>
>> Is that intended behavior or a bug? I can't see why the getMember trait
>> should not be able to retrieve private members when allMembers trait is
>
> Can you use a string instead of getMember?
You mean something like this:
foreach (member; __traits(allMembers, TestClass))
{
static if (member == "value")
{
pragma(msg, __traits(getProtection, member));
}
}
That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
|
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin | On 06/21/13 15:27, Martin wrote:
> On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
>> On 2013-06-21 15:04, Martin wrote:
>>> module test;
>>>
>>> void test()
>>> {
>>>
>>>
>>> foreach (member; __traits(allMembers, Client))
>>> {
>>> pragma(msg, member); // Prints all members fine, including "value"
>>> }
>>>
>>> // This line fails
>>> static if(__traits(getProtection, __traits(getMember, TestClass,
>>> "value")) == "public")
>>> {
>>> pragma(msg, "value is public");
>>> }
>>> else
>>> {
>>> pragma(msg, "value is not public");
>>> }
>>>
>>> }
>>>
>>> module testclass;
>>>
>>> class TestClass
>>> {
>>> private:
>>> int value;
>>> }
>>>
>>> When using the allMembers trait, the private "value" member of TestClass is included, but when trying to retrieve that member using the getMember trait, it fails to compile with test.d(13): Error: class main.TestClass member value is not accessible
>>>
>>> Is that intended behavior or a bug? I can't see why the getMember trait should not be able to retrieve private members when allMembers trait is
>>
>> Can you use a string instead of getMember?
>
> You mean something like this:
>
> foreach (member; __traits(allMembers, TestClass))
> {
> static if (member == "value")
> {
> pragma(msg, __traits(getProtection, member));
> }
> }
>
> That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
pragma(msg, __traits(getProtection, mixin("TestClass." ~ member)));
artur
|
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Friday, 21 June 2013 at 13:42:44 UTC, Artur Skawina wrote:
> On 06/21/13 15:27, Martin wrote:
>> On Friday, 21 June 2013 at 13:15:43 UTC, Jacob Carlborg wrote:
>>> On 2013-06-21 15:04, Martin wrote:
>>>> module test;
>>>>
>>>> void test()
>>>> {
>>>>
>>>>
>>>> foreach (member; __traits(allMembers, Client))
>>>> {
>>>> pragma(msg, member); // Prints all members fine, including "value"
>>>> }
>>>>
>>>> // This line fails
>>>> static if(__traits(getProtection, __traits(getMember, TestClass,
>>>> "value")) == "public")
>>>> {
>>>> pragma(msg, "value is public");
>>>> }
>>>> else
>>>> {
>>>> pragma(msg, "value is not public");
>>>> }
>>>>
>>>> }
>>>>
>>>> module testclass;
>>>>
>>>> class TestClass
>>>> {
>>>> private:
>>>> int value;
>>>> }
>>>>
>>>> When using the allMembers trait, the private "value" member of TestClass
>>>> is included, but when trying to retrieve that member using the getMember
>>>> trait, it fails to compile with test.d(13): Error: class main.TestClass
>>>> member value is not accessible
>>>>
>>>> Is that intended behavior or a bug? I can't see why the getMember trait
>>>> should not be able to retrieve private members when allMembers trait is
>>>
>>> Can you use a string instead of getMember?
>>
>> You mean something like this:
>>
>> foreach (member; __traits(allMembers, TestClass))
>> {
>> static if (member == "value")
>> {
>> pragma(msg, __traits(getProtection, member));
>> }
>> }
>>
>> That works, but it prints "public", even though the "value" member is private. Surprisingly strange behavior
>
> pragma(msg, __traits(getProtection, mixin("TestClass." ~ member)));
>
> artur
Thanks, that sort of works. It prints "private" but then immediately gives an error:
test.d(12): Error: class main.TestClass member value is not accessible
Sigh, this is DMD 2.063.2 by the way.
|
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin | On 2013-06-21 15:50, Martin wrote: > Thanks, that sort of works. It prints "private" but then immediately > gives an error: > test.d(12): Error: class main.TestClass member value is not accessible > > Sigh, this is DMD 2.063.2 by the way. That sucks. Time for a bugzilla report. http://d.puremagic.com/issues/ -- /Jacob Carlborg |
June 21, 2013 Re: allMembers and getMember traits behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Martin | On 06/21/13 15:50, Martin wrote:
> On Friday, 21 June 2013 at 13:42:44 UTC, Artur Skawina wrote:
>>> pragma(msg, __traits(getProtection, mixin("TestClass." ~ member)));
> Thanks, that sort of works. It prints "private" but then immediately gives an error: test.d(12): Error: class main.TestClass member value is not accessible
>
> Sigh, this is DMD 2.063.2 by the way.
Sorry, didn't test that one, just used the right symbol; it has the same
problem as your original issue. Clearly, the getProtection trait wasn't
designed with inaccesible symbols in mind. And no, 'getMember' bypassing
the protection would not be a good idea (would make it too easy to mistakenly
access private data in generic code). getProtection should probably just
take two args, just like getMember, which would allow it to safely ignore
the normal access rules.
Right now, you can use 'tupleof', which bypasses the visibility attrs:
alias T = TestClass;
foreach (I, TYPE; typeof(T.tupleof)) {
pragma(msg, __traits(getProtection, T.tupleof[I]), " ",
TYPE, " ",
__traits(identifier, T.tupleof[I]), ";");
}
artur
|
Copyright © 1999-2021 by the D Language Foundation