[Question] About mixin, template and alias
monarch_dodra
monarchdodra at gmail.com
Sun Sep 22 14:02:09 PDT 2013
On Sunday, 22 September 2013 at 18:31:20 UTC, Michael wrote:
> /////// fire.d
>
> import std.stdio;
>
> alias void delegate() EventHandler;
>
> class Event(T)
> {
> private T[] _events;
>
> public void opOpAssign(string op)(T param) if (op == "~")
> {
> writeln(param.funcptr);
> _events ~= param;
> }
>
> public void opCall(ParamType ...)(ParamType params)
> {
> emit(params);
> }
>
> protected void emit(ParamType ...)(ParamType params)
> {
> foreach (event; _events)
> event(params);
> }
> }
>
> mixin template AddEvent(DelegateType, string member)
> {
> auto eventObserver = new Event!DelegateType();
>
> mixin("alias eventObserver " ~ member ~ ";");
> }
>
> class Fire
> {
> public mixin AddEvent!(EventHandler, "click");
> }
>
> /////// water.d
> import std.stdio;
>
> import fire;
>
> class Water : Fire
> {
>
> }
>
> void main()
> {
> auto fire = new Fire();
> auto water = new Water();
> water.click ~= () { writeln("Water!"); };
> fire.click ~= () { writeln("Fire!"); };
>
> fire.click();
> }
>
>
> Output:
> Water!
> Fire!
>
> Someone can explain me a behaviour of above code? Why not
> "Fire!" only?
This:
//----
auto eventObserver = new Event!DelegateType();
//----
Does not do what you think it does: It *statically* initializes
"eventObserver" to the *single* "new Event!DelegateType();". SO
basically, all your instances are sharing the same Event.
I'm surprised this compiles at all, what with Fire.init depending
on a run-time call, but apparently, dmd is "smart enough" to do
the allocation at compile time.
More information about the Digitalmars-d-learn
mailing list