Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 26, 2016 [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
``` 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? |
December 26, 2016 Re: [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
Posted in reply to crimaniak | 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.
|
December 26, 2016 Re: [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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? |
December 26, 2016 Re: [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
Posted in reply to crimaniak | 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
|
December 27, 2016 Re: [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. |
December 27, 2016 Re: [question] Access from UDA constructor to parent symbol | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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.
|
Copyright © 1999-2021 by the D Language Foundation