www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - super(...) in mixin template

reply "Steve Teale" <steve.teale britseyeview.com> writes:
I did not get any takers in D Learn, so I'll try again here.

Mixin templates are supposed to be instantiated in the scope 
where they were invoked. I have tried one that I want to invoke 
in the body of a constructor, but it fails when it calls 
super(...).

Should this be so, or is it a bug?

Steve
Mar 03 2014
next sibling parent "Meta" <jared771 gmail.com> writes:
On Monday, 3 March 2014 at 16:11:48 UTC, Steve Teale wrote:
 I did not get any takers in D Learn, so I'll try again here.

 Mixin templates are supposed to be instantiated in the scope 
 where they were invoked. I have tried one that I want to invoke 
 in the body of a constructor, but it fails when it calls 
 super(...).

 Should this be so, or is it a bug?

 Steve

Can you post a link to the thread in digitalmars.D.learn? I regularly lurk there, and I must've missed your thread.
Mar 03 2014
prev sibling next sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Monday, 3 March 2014 at 16:11:48 UTC, Steve Teale wrote:
 I did not get any takers in D Learn, so I'll try again here.

 Mixin templates are supposed to be instantiated in the scope 
 where they were invoked. I have tried one that I want to invoke 
 in the body of a constructor, but it fails when it calls 
 super(...).

 Should this be so, or is it a bug?

 Steve

Have you got an example please?
Mar 03 2014
prev sibling next sibling parent "Steve Teale" <steve.teale britseyeview.com> writes:
On Monday, 3 March 2014 at 16:20:22 UTC, Gary Willoughby wrote:
 On Monday, 3 March 2014 at 16:11:48 UTC, Steve Teale wrote:
 I did not get any takers in D Learn, so I'll try again here.

 Mixin templates are supposed to be instantiated in the scope 
 where they were invoked. I have tried one that I want to 
 invoke in the body of a constructor, but it fails when it 
 calls super(...).

 Should this be so, or is it a bug?

 Steve

Have you got an example please?

There's an example below, but it is probably not necessary. The thing is that the mixin won't compile because it's seeing super(whatever) as an attempt to define a function. mixin.d(35): Error: function declaration without return type. (Note that constructors are always named 'this') mixin.d(35): Error: no identifier for declarator super(s, t, g) If you move the mixin definition inside a constructor, you get a slew of other errors. What I really want the mixin to do should I think be done after the class hierarchy is complete - without the super call the rest of it is hardly worth bothering. I should also mention that the example below compiles OK if you move the super call out of the mixin, but for some reason it won't link - it works OK in my app, so I didn't pursue it. import std.conv; enum { COX, WILLIAM, GREEN } enum Groups { APPLES, PEARS, BANANAS } class App { this(); } class Base { string name; int type; Groups group; mixin template Preamble(alias NAME, alias GNAME, alias T) { string s = NAME~" "~to!string(nextOid); Groups g = mixin("Groups."~GNAME); static int t = T; // Mixin must be syntactically correct - the following isn't because // we are not in a constructor super(s, t, g); } this(App app, string s, int t, Groups g) { name = s; type = t; group = g; } } class Intermediate : Base { this(App app, string s, int t, Groups g) { super(app, s, t, g); } } class CoxPipin : Intermediate { static int nextOid = 0; this(App app) { mixin Preamble!("CoxPipin", "APPLES", COX); // Move the super call out, and everything is fine //super(app, s, t, g); } } void main() { App a = new App(); Base x = new CoxPipin(a); }
Mar 03 2014
prev sibling next sibling parent "Jacob Carlborg" <doob me.com> writes:
On Tuesday, 4 March 2014 at 05:08:45 UTC, Steve Teale wrote:

 There's an example below, but it is probably not necessary.

 The thing is that the mixin won't compile because it's seeing 
 super(whatever) as an attempt to define a function.

Perhaps you already figured this out but template mixins can only mixin declarations, not expression or statements. -- /Jacob Carlborg
Mar 03 2014
prev sibling next sibling parent "Steve Teale" <steve.teale britseyeview.com> writes:
On Tuesday, 4 March 2014 at 07:23:29 UTC, Jacob Carlborg wrote:
 Perhaps you already figured this out but template mixins can 
 only mixin declarations, not expression or statements.

 --
 /Jacob Carlborg

Damn! Yup, first sentence of the documentation. Wishful reading. Thanks. Steve
Mar 04 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 4 March 2014 at 10:37:02 UTC, Steve Teale wrote:
 On Tuesday, 4 March 2014 at 07:23:29 UTC, Jacob Carlborg wrote:
 Perhaps you already figured this out but template mixins can 
 only mixin declarations, not expression or statements.

 --
 /Jacob Carlborg

Damn! Yup, first sentence of the documentation. Wishful reading. Thanks. Steve

You can of course mixin a function (either nested inside the constructor or as a member or even a free funtion) containing whatever you want and then call that. That won't help you with calling super() though, you can only call super from another constructor. You'd have to use a string mixin as that truly can inject arbitrary code.
Mar 04 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 4 March 2014 at 12:01:46 UTC, John Colvin wrote:
 On Tuesday, 4 March 2014 at 10:37:02 UTC, Steve Teale wrote:
 On Tuesday, 4 March 2014 at 07:23:29 UTC, Jacob Carlborg wrote:
 Perhaps you already figured this out but template mixins can 
 only mixin declarations, not expression or statements.

 --
 /Jacob Carlborg

Damn! Yup, first sentence of the documentation. Wishful reading. Thanks. Steve

You can of course mixin a function (either nested inside the constructor or as a member or even a free funtion) containing whatever you want and then call that. That won't help you with calling super() though, you can only call super from another constructor. You'd have to use a string mixin as that truly can inject arbitrary code.

This opens a question: Should functions nested in constructors be given all the same powers that a constructor has (calling super, initializing const/immutable data etc)?
Mar 04 2014
prev sibling next sibling parent "luminousone" <rd.hunt gmail.com> writes:
On Tuesday, 4 March 2014 at 12:04:12 UTC, John Colvin wrote:
 On Tuesday, 4 March 2014 at 12:01:46 UTC, John Colvin wrote:
 On Tuesday, 4 March 2014 at 10:37:02 UTC, Steve Teale wrote:
 On Tuesday, 4 March 2014 at 07:23:29 UTC, Jacob Carlborg 
 wrote:
 Perhaps you already figured this out but template mixins can 
 only mixin declarations, not expression or statements.

 --
 /Jacob Carlborg

Damn! Yup, first sentence of the documentation. Wishful reading. Thanks. Steve

You can of course mixin a function (either nested inside the constructor or as a member or even a free funtion) containing whatever you want and then call that. That won't help you with calling super() though, you can only call super from another constructor. You'd have to use a string mixin as that truly can inject arbitrary code.

This opens a question: Should functions nested in constructors be given all the same powers that a constructor has (calling super, initializing const/immutable data etc)?

http://d.puremagic.com/issues/show_bug.cgi?id=3332 I would bet you can't call super from a mixin.
Mar 04 2014
prev sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 5 March 2014 at 04:05:56 UTC, luminousone wrote:
 On Tuesday, 4 March 2014 at 12:04:12 UTC, John Colvin wrote:
 On Tuesday, 4 March 2014 at 12:01:46 UTC, John Colvin wrote:
 On Tuesday, 4 March 2014 at 10:37:02 UTC, Steve Teale wrote:
 On Tuesday, 4 March 2014 at 07:23:29 UTC, Jacob Carlborg 
 wrote:
 Perhaps you already figured this out but template mixins 
 can only mixin declarations, not expression or statements.

 --
 /Jacob Carlborg

Damn! Yup, first sentence of the documentation. Wishful reading. Thanks. Steve

You can of course mixin a function (either nested inside the constructor or as a member or even a free funtion) containing whatever you want and then call that. That won't help you with calling super() though, you can only call super from another constructor. You'd have to use a string mixin as that truly can inject arbitrary code.

This opens a question: Should functions nested in constructors be given all the same powers that a constructor has (calling super, initializing const/immutable data etc)?

http://d.puremagic.com/issues/show_bug.cgi?id=3332

I don't see how that's relevant? The crux of that request/bug is about overload resolution.
Mar 05 2014