digitalmars.D.learn - [question] Access from UDA constructor to parent symbol
- crimaniak (15/15) Dec 26 2016 ```
- Adam D. Ruppe (8/10) Dec 26 2016 then pass foo to it....
- crimaniak (49/60) Dec 26 2016 I mean the character to which the attribute belongs, Foo in this
- =?UTF-8?Q?Ali_=c3=87ehreli?= (21/22) Dec 26 2016 Just to make sure we're on the same page: :)
- crimaniak (12/33) Dec 27 2016 Interface implementation has a significant advantage over
- Jerry (24/35) Dec 27 2016 I think he wants the symbol that the UDA is attached to.
``` 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
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
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 mean the character to which the attribute belongs, Foo in this case.// 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.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
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
On Tuesday, 27 December 2016 at 02:05:27 UTC, Ali Çehreli wrote:On 12/26/2016 02:04 PM, crimaniak wrote:Yes. I want it for structs exactly.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.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
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 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.// 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 27 2016