digitalmars.D.learn - Cascading, variable mixins
- Slavisa Radic <konfusious gmx.de> Oct 01 2007
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Oct 01 2007
- Slavisa Radic <konfusious gmx.de> Oct 01 2007
- BCS <ao pathlink.com> Oct 01 2007
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
"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
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
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









Slavisa Radic <konfusious gmx.de> 