Welcome to This Week in D! Each week, we'll summarize what's been going on in the D community and write brief advice columns to help you get the most out of the D Programming Language.
The D Programming Language is a general purpose programming language that offers modern convenience, modeling power, and native efficiency with a familiar C-style syntax.
This Week in D has an RSS feed.
This Week in D is edited by Adam D. Ruppe. Contact me with any questions, comments, or contributions.
Apparently, the ddoc generator in the newest dmd beta has radically changed. If you use dmd's ddoc and changed to the beta, inspect your generated code and make sure your custom style sheets still apply.
See more at the announce forum.
When working with class inheritance, it is possible to call a method from a base class, even when it is overridden by a child class, by using the specific class name at the call site. Observe:
import std.stdio; class ClassA { void fun() { writeln("A"); } } class ClassB : ClassA { override void fun() { writeln("B"); } } void main() { auto cb = new ClassB; cb.fun(); // "B" cb.ClassA.fun(); // "A" cb.ClassB.fun(); // "B" }
The first line, cb.fun, does a normal virtual dispatch. It will call the bottom-most class override. The second line specifically asks for the function from ClassA, bypassing the virtual override mechanism. The third line does the same, but for ClassB's version.
Usually, you wouldn't want to do this because methods are overridden in a subclass for a reason. There may be additional state to maintain, for example. Inside the class definition, you can use the super keyword to call the parent class's implementation (e.g. override void fun() { super.fun(); }), so you don't need to specify its name there either.
But, this technique makes it possible at the call site for the times when you do. One of the more common use cases is if your class inherits from two interfaces and each has a method of the same name, but they do different things. You can then disambiguate with the interface name:
interface A { int get(); } interface B { string get(); } class C : A, B { int get() { return 0; } string get() { return ""; } } void main() { auto c = new C(); //c.get(); /* $ dmd qqq qqq.d(16): Error: qqq.C.get called with argument types () matches both: qqq.d(10): qqq.C.get() and: qqq.d(11): qqq.C.get() */ int a = c.A.get(); // works string b = c.B.get(); // works }
The error message given in the first line is a tricky one! To the new reader, it would look like nonsense, has dmd lost its mind? But such can happen when a method differs only by return value. Automatic overload resolution never considers return values, so to work with such a situation, you need to specify the interface you want using the name method above.
To learn more about D and what's happening in D: