On Monday, 24 February 2014 at 18:59:32 UTC, Steven Schveighoffer
wrote:
On Mon, 24 Feb 2014 11:36:50 -0500, Frustrated
<c1514...@drdrb.com> wrote:
http://dpaste.dzfl.pl/c25655e2dfe9
The code above simplifies using interfaces as the programming
object. It allows one to program the derived classes as if they
were not part of an abstraction by mapping the abstracted
virtual
methods to concrete methods.
e.g.,
class WindowsGui : iGui
{
WindowsButton _button;
@property WindowsButton button(WindowsButton b) { return
(_button = b); }
mixin(Fixup!(WindowsGui, iButton, WindowsButton));
}
instead of
class WindowsGui : iGui
{
WindowsButton _button;
@property iButton button(iButton b)
{
assert(cast(WindowsButton)b !is null, `Invalid
object
type dependency mismatch! Type: `~b.classinfo.name~` Type
Expected: WindowsButton`);
auto bb = cast(WindowsButton)b;
// do work with bb.
}
}
Nice work!
One problem with the template is that b.classinfo.name returns
the interface instead of the actual class.
Hm... classinfo (now typeid) should get the most derived type
from an instance. This may be a factor of it being an interface
instance vs. a class instance. A simple test:
Stevens-MacBook-Pro:~ steves$ cat testinterface.d
import std.stdio;
interface I
{
}
class C : I
{
}
void main()
{
I i = new C;
writeln(typeid(i).name);
writeln(typeid(cast(Object)i).name);
}
Stevens-MacBook-Pro:~ steves$ ./testinterface
testinterface.I
testinterface.C
Looks like that is the case. Note that classinfo is not part of
the language any more, and will likely be deprecated. typeid is
the correct mechanism to get the TypeInfo of a derived class.
I'm thinking this is incorrect, typeid should get the derived
class type IMO. It shouldn't be that difficult or costly for
the compiler to do.
Thanks. Now the correct type is known. One could, for example,
look for wrappers/adapters/etc to get a linuxbutton into a
windowsbutton(if so desired, throw a well informed error, etc.
Hopefully though, now you see the point. It is a runtime contract
that you make since you can't specify it at compile time(since D
doesn't supports it).
In any case the mixin needs some work and testing. Would just
like to get the proper class name for the type. It is, at the
very least, a proof of concept.
Unfortunately the main downside is the vtable is twice as big.
Final or static methods could be used for this. If the compiler
could manage such a system it could do the job better. (There
would be no extra functions needed and the calls would be faster)
The issue is this: I want to program to interfaces(requiring the
class(WindowsGui) to use base interfaces(iButton) to satisfy the
interface.
The problem is this compile time contract is to generic and makes
coding the classes more verbose. The mixin reduces the verbosity
and provides a runtime contract(we enforce it using asserts in
this case).
The benefit of the mixin is that coding WindowsGui is simpler and
more direct and it's dependency on WindowsButton(not iButton) is
known at compile time(But enforced at runtime by assert). Would
you not agree? Everything else is essentially identical.