Inheritance of mixin

Basile B. via Digitalmars-d digitalmars-d at puremagic.com
Thu Apr 28 05:41:57 PDT 2016


On Thursday, 28 April 2016 at 10:21:34 UTC, Andrew Benton wrote:
> I'm running into a set of problems where both inheritance and 
> mixin-added functionality really lend a hand to my project.  
> Unfortunately, they don't necessarily work well together, as 
> certain mixins need to be restated for each inheritor.
>
> As a toy example, if I wanted to mixin some functionality to 
> write names:
>
> mixin template WriteName()
> {
>     string writeName()
>     {
>         import std.uuid : randomUUID;
>         static if(__traits(hasMember, this, "name"))
>             return __traits(getMember, this, "name);
>         else
>             return randomUUID.toString;
>     }
> }
> class Base
> {
>     mixin WriteName;
> }
> class Inheritor : Base
> {
>     version(both) mixin WriteName;
>     string name = "test";
> }
>
> In the above example, unless I used version "both", I would see 
> only random UUIDs from instances of Base and Inheritor, however 
> the functionality that I really want is to get random UUIDs 
> only from Base, and get "test" from Inheritor.  So far as I 
> know, the easiest way to fix this is to add that mixin to each 
> descendant of Base.
>
> I recognize that, at least for this toy example, an easier fix 
> is to use a templated function, however I'm more interested in 
> libraries like jsonizer and witchcraft.
>
> So to the point: Is there an easier way to do this that I'm 
> missing?  Is there a language-design reason that mixed in 
> templates can't inherit?  It seems like an intuitive use of 
> mixin.

This is a common error with mixin template. The static things 
gets only evaluated once. If you want to be evaluated in each 
class type you need a true template that get an instance in each 
class. However the method then **wont be virtual** !!

----
mixin template WriteName()
{
     string writeName(this T)()
     {
         import std.uuid : randomUUID;
         static if (__traits(hasMember, T, "name"))
             return __traits(getMember, cast(T)this, "name");
         else
             return randomUUID.toString;
     }
}
class Base
{
     mixin WriteName;
}
class Inheritor : Base
{
     string name = "test";
}

void main()
{
     import std.stdio;
     writeln((new Base).writeName!Base); // an UUID
     writeln((new Inheritor).writeName!Inheritor); // test
}
----

see template this parameter:

https://dlang.org/spec/template.html#TemplateThisParameter


More information about the Digitalmars-d mailing list