www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - hijacking override from template mixin

reply "Ivan Kazmenko" <gassa mail.ru> writes:
The D language pays certain attention to avoiding hijacking [1].  
So I was surprised when I hijacked a function override from a 
template mixin by mistake.  Here is a commented example.  The 
comments explain the relevant part of the life cycle of the 
program.

-----
// Start with class A with method fun returning "A".
class A {
     string fun () {return "A";}
}

// Subclass B will return "B" instead.
class B: A {
     override string fun () {return "B";}
}

// Turns out a common need is to return "MT",
// so we will create a mixin template MT for it
// to reduce boilerplate.
mixin template MT () {
     override string fun () {return "MT";}
}

// We use MT in our new subclass C.
class C: A {
     mixin MT;
}

// Both a mixed-in override and a regular one
// by a refactoring mistake, what happens?
class D: A {
     mixin MT;
     override string fun () {return "D";}
}

// Let's find out.
void main () {
     import std.stdio;
     writeln (new B ().fun ()); // B
     writeln (new C ().fun ()); // MT
     writeln (new D ().fun ()); // D, not MT
}
-----

I'd expect a "multiple overrides of same function" error, much 
like if I just paste the mixin code by hand.  Is that a bug or 
working by design?  In the latter case, please explain the 
reasoning.

Also, if there is a "better" tool than a template mixin in the 
situation explained in the comments, please point me to it.

[1] http://dlang.org/hijack.html
Jun 09 2014
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 9 June 2014 at 15:54:21 UTC, Ivan Kazmenko wrote:
 I'd expect a "multiple overrides of same function" error, much 
 like if I just paste the mixin code by hand.  Is that a bug or 
 working by design?  In the latter case, please explain the 
 reasoning.
AFAIK, the rationale is that *should* a colision happen, the local symbol shadows the mixed-in symbol. Doing this avoid breaking your code just because someone added an extra member in their mixin, which happened to conflict with one of yours. The idea is that you can workaround the issue by "naming" your mixin templates. Then, when you want to access members of the mixin template, you *know* it'll always work, regardless of what else may have been declared in your class. That said, for something like virrtual functions, things get a bit trickier, since your *aren't* supposed to call them explicitly... I don't know if bug, or just surprising behavior.
Jun 09 2014
parent "Ivan Kazmenko" <gassa mail.ru> writes:
On Monday, 9 June 2014 at 16:13:50 UTC, monarch_dodra wrote:
 On Monday, 9 June 2014 at 15:54:21 UTC, Ivan Kazmenko wrote:
 I'd expect a "multiple overrides of same function" error, much 
 like if I just paste the mixin code by hand.  Is that a bug or 
 working by design?  In the latter case, please explain the 
 reasoning.
AFAIK, the rationale is that *should* a colision happen, the local symbol shadows the mixed-in symbol. Doing this avoid breaking your code just because someone added an extra member in their mixin, which happened to conflict with one of yours. The idea is that you can workaround the issue by "naming" your mixin templates. Then, when you want to access members of the mixin template, you *know* it'll always work, regardless of what else may have been declared in your class. That said, for something like virrtual functions, things get a bit trickier, since your *aren't* supposed to call them explicitly... I don't know if bug, or just surprising behavior.
Thank you for the explanation! I've thought since that for classes, a template mixin of such kind can, and perhaps should, be replaced by inheritance from abstract classes or interfaces. There's likely no performance hit since the virtual table is already there anyway. Still, I consider reporting this case as a maybe-bug to see more opinions. At least such shadowing is a case for a static code analysis tool. Ivan Kazmenko.
Jun 10 2014
prev sibling parent "sigod" <sigod.mail gmail.com> writes:
On Monday, 9 June 2014 at 15:54:21 UTC, Ivan Kazmenko wrote:
 I'd expect a "multiple overrides of same function" error, much 
 like if I just paste the mixin code by hand.  Is that a bug or 
 working by design?  In the latter case, please explain the 
 reasoning.
http://dlang.org/template-mixin.html says:
 The declarations in a mixin are ‘imported’ into the surrounding 
 scope. If the name of a declaration in a mixin is the same as a 
 declaration in the surrounding scope, the surrounding 
 declaration overrides the mixin one.
Jun 14 2014