www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - [question] Access from UDA constructor to parent symbol

reply crimaniak <crimaniak gmail.com> writes:
```
class uda
{
     this()
     {
          // I want to see Foo here and use it's reflection to 
iterate fields and methods.
     }
}


 uda
struct Foo
{

}

```
Is there a way to do it?
Dec 26 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 26 December 2016 at 20:07:56 UTC, crimaniak wrote:
          // I want to see Foo here and use it's reflection to 
 iterate fields and methods.
then pass foo to it.... What do you mean parent symbol? I assumed you mean subclass but your example shows one class and one struct. So is it the structure containing the class? Or what? But, the answer of just passing the argument is probably the best one anyway. You can use a factory function, or pass the type from a constructor to a super method, or something like that.
Dec 26 2016
next sibling parent reply crimaniak <crimaniak gmail.com> writes:
On Monday, 26 December 2016 at 21:15:03 UTC, Adam D. Ruppe wrote:
 On Monday, 26 December 2016 at 20:07:56 UTC, crimaniak wrote:
          // I want to see Foo here and use it's reflection to 
 iterate fields and methods.
then pass foo to it.... What do you mean parent symbol? I assumed you mean subclass but your example shows one class and one struct. So is it the structure containing the class? Or what?
I mean the character to which the attribute belongs, Foo in this case.
 But, the answer of just passing the argument is probably the 
 best one anyway. You can use a factory function, or pass the 
 type from a constructor to a super method, or something like 
 that.
Let me explain. I want to have struct Foo : BarInterface {}. I read forums and found some discussion. Arguments against this feature has no sense on my opinion. But in fact I don't think it will be implemented. So I try to implement it as library. My idea: class implements(Interface) { this() { // iterate all members of Interface and check if this element // exists in parent symbol and check if parameters the same. // Write clean error message if contract fails. } } unittest { interface I1 { void foo(); int bar(int i); } implements!I1 struct S1 { void foo() { import std.stdio; writeln("foo"); } // I want error message like "function int bar(int i) should be implemented according to interface I1" in this case } } So, if I pass both types in parameters it will not be so clean. It will be some separate from struct expression, but I want attribute like above. It seems I can find symbol iterating all symbols in __MODULE__but in this case it will be O(N^2), there N is amount of implements usages in module. I also thought about such option: struct S1 { mixin implements!I1; ... } But this option I like less, and I have not researched it. So my main question: how it is possible to do such thing?
Dec 26 2016
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/26/2016 02:04 PM, crimaniak wrote:

 So my main question: how it is possible to do such thing?
Just to make sure we're on the same page: :) * There is 'interface' in addition to 'class' * If all you want is to check, then you can write template constraints by following the example of std.range.isInputRange. With that aside, what you need is generally achieved by a mixin: implements!I1 struct S1 { // ... } template ValidateInterfaces() { // Go through all members of the module here // Identify the ones having the 'implements' UDA // The useful tools here are // __traits(getAttributes) // __traits(allMembers) // __traits(getMember) } mixin ValidateInterfaces; Ali
Dec 26 2016
parent crimaniak <crimaniak gmail.com> writes:
On Tuesday, 27 December 2016 at 02:05:27 UTC, Ali Çehreli wrote:
 On 12/26/2016 02:04 PM, crimaniak wrote:

 So my main question: how it is possible to do such thing?
Just to make sure we're on the same page: :) * There is 'interface' in addition to 'class'
Yes. I want it for structs exactly.
 * If all you want is to check, then you can write template 
 constraints by following the example of std.range.isInputRange.
Interface implementation has a significant advantage over template constraints for implementation break case. With interface I have one relevant error on the implementation stage. With template constraints I have many less relevant errors on the usage stage. It's just different types of contract.
 With that aside, what you need is generally achieved by a mixin:

  implements!I1
 struct S1
 {
     // ...
 }

 template ValidateInterfaces() {
     // Go through all members of the module here
     // Identify the ones having the 'implements' UDA
     // The useful tools here are
     //     __traits(getAttributes)
     //     __traits(allMembers)
     //     __traits(getMember)
 }

 mixin ValidateInterfaces;
Thanks, this is a way. The only problem user can forget to call this mixin. It would be useful to have module-wide compile-time variables, in this case it's possible to call ValidateInterfaces one time from first implements instance and user don't have to write it at every module.
Dec 27 2016
prev sibling parent Jerry <hurricane hereiam.com> writes:
On Monday, 26 December 2016 at 21:15:03 UTC, Adam D. Ruppe wrote:
 On Monday, 26 December 2016 at 20:07:56 UTC, crimaniak wrote:
          // I want to see Foo here and use it's reflection to 
 iterate fields and methods.
then pass foo to it.... What do you mean parent symbol? I assumed you mean subclass but your example shows one class and one struct. So is it the structure containing the class? Or what? But, the answer of just passing the argument is probably the best one anyway. You can use a factory function, or pass the type from a constructor to a super method, or something like that.
I think he wants the symbol that the UDA is attached to. So instead of doing: struct attribN(I, T) { } attrib1!(Implement1, MyStructName) attrib2!(Implement2, MyStructName) struct MyStructName { } you could instead possibly add a feature to do this: struct attribN(I, T = __UDA__) { } // or possibly class attribN(I) : Attribute // Attribute then contains the symbol its connected to { } attrib1!Implement1 attrib2!Implement2 struct MyStructName { } Not likely a feature to be added though.
Dec 27 2016