www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cascading, variable mixins

reply Slavisa Radic <konfusious gmx.de> writes:
Hello Folks,

I would like to augment a mixin with another mixin, which gets augmented by
another mixin...and so forth

The most important design goal is, how to pass a mixin as parameter and the
class which gets augmented by the mixin does not has to import the mixin.

My overall-goal is to be able to extend functionality of a class from outside,
without the need to touch the class itself (kind of inter-type-declaration).

I managed to pass a template as an alias parameter to the class which was going
to be augmented. This class was able to mix it in.

Next i tried to do the same with the template which gets mixed in. I
parameterized it with an alias-parameter, and used the parameter as mixin.

However, this doesn't work. In order to parameterize the template, I had to
instantiate it. This instantiated template then could not get mixed in in the
class, as it was no template-name any-more.

To illustrate this a little bit:
---------------------------
import std.stdio;

class A(alias T)
{
    mixin T;
}
-------------------------

module b;
import std.stdio;

template B(alias T)
{
    public void foo()
    {
        writefln("This is template-code from Template B");
    }

    mixin T;
}
-------------------------------------------------------------------

module b2;

template B2()
{
    public void bar()
    {

        writefln("And This is Code from a different Template, namely Template
B2");
    }
}
--------------------------------
private import a;
private import b;
private import b2;

int main(char[][] args)
{
    A! ( B! (B2) ) a = new A! ( B! (B2) ) ();
    a.foo();
    a.bar();
    return 0;
}
--------------------------------------------

Compiling this will result in the following error:
a.d:5: mixin T is not a template

And it's true. It is really no template as it gets instantiated in the
main-function. The problem is, how to parameterize B without instantiating it?

I would realy apreciate it If somebody would have a solution for this, as I
need it for my Master-Thesis. So please do not post comments like "why should
somebody do such stuff" - there are people - e.g. me ;-)
Oct 01 2007
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Slavisa Radic" <konfusious gmx.de> wrote in message 
news:fdqo5g$2prv$1 digitalmars.com...
 To illustrate this a little bit:
 ---------------------------
 import std.stdio;

 class A(alias T)
 {
    mixin T;
 }
 -------------------------

 module b;
 import std.stdio;

 template B(alias T)
 {
    public void foo()
    {
        writefln("This is template-code from Template B");
    }

    mixin T;
 }
 -------------------------------------------------------------------

 module b2;

 template B2()
 {
    public void bar()
    {

        writefln("And This is Code from a different Template, namely 
 Template B2");
    }
 }
 --------------------------------
 private import a;
 private import b;
 private import b2;

 int main(char[][] args)
 {
    A! ( B! (B2) ) a = new A! ( B! (B2) ) ();
    a.foo();
    a.bar();
    return 0;
 }
 --------------------------------------------

Try something like.. class A(alias T, Args...) { mixin T!(Args); } ... auto a = new A!(B, B2)(); a.foo(); a.bar(); WOrks for me :)
Oct 01 2007
parent Slavisa Radic <konfusious gmx.de> writes:
hmm, ok, now we managed to extend the class without touching it. But
unfortunatly, I forgot to mention that the templates shouldn't be touched from
outside either. So the goal is to build a set of refinements of classes, which
then should be plugged together in the main-method, in order to produce desired
classes.

Your proposal was to make the amount of template-parameters for the
target-class variadic. That leads to the necessity of changing the templates
(template b) parameter-list.

What i'm looking for, is a way to build chains of mixins with arbitrary depth.
The proposed solution is just of depth 2.

Your Solution:

a mixes in b
b mixes in b2
b mixes in b3
b mixes in b4
and so forth...

But I'm looking for a way to do:

a mixes in b
b mixes in b2
b2 mixes in b3
b3 mixes in b4
and so forth

But thanks for your interesting suggestion.
Oct 01 2007
prev sibling parent BCS <ao pathlink.com> writes:
Reply to Slavisa,

 To illustrate this a little bit:

import std.stdio; class A(alias T) { mixin T; } ------------------------- module b; import std.stdio; template B(alias T) { public void foo() { writefln("This is template-code from Template B"); } mixin T; } ------------------------------------------------------------------- module b2; template B2() { public void bar() { writefln("And This is Code from a different Template, namely Template B2"); } } -------------------------------- private import a; private import b; private import b2; int main(char[][] args) { A! ( B! (B2) ) a = new A! ( B! (B2) ) (); a.foo(); a.bar(); return 0; } --------------------------------------------

I haven't tried it but this may work template B(alias T) { template inner() { public void foo() { writefln("This is template-code from Template B"); } mixin T; } } class A(alias T) { mixin T.inner; } auto a = new A! ( B!(B2) ) ();
Oct 01 2007