<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2013/7/4 JS <span dir="ltr"><<a href="mailto:js.mdnq@gmail.com" target="_blank">js.mdnq@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I'm trying to write a mixin that will solve the problem but since I can't seem to build up strings progressively it's a huge pain in the ass.<br></blockquote><div></div></div><br></div><div class="gmail_extra">
How about this?</div><div class="gmail_extra">Unfortunately this code doesn't work with git head, because it requires both one small std.typecons.wrap bug fix and its one small improvement. But I'll make a PR to fix them soon.</div>
<div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">// -------------</div><div class="gmail_extra">// core side</div><div class="gmail_extra"><br></div><div class="gmail_extra">import std.typecons : Proxy;</div>
<div class="gmail_extra">import std.typecons : wrap, unwrap;</div><div class="gmail_extra">import std.typecons : WhiteHole, NotImplementedError;</div><div class="gmail_extra">import std.exception : enforce;</div><div class="gmail_extra">
<br></div><div class="gmail_extra">public interface Interface</div><div class="gmail_extra">{</div><div class="gmail_extra">    int foo();</div><div class="gmail_extra">    int bar();</div><div class="gmail_extra">}</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">private class Pluggable</div><div class="gmail_extra">{</div><div class="gmail_extra">    Interface impl;</div><div class="gmail_extra">    mixin Proxy!impl;</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">    static Interface defaultImpl;</div><div class="gmail_extra">    static this() { defaultImpl = new WhiteHole!Interface(); }</div><div class="gmail_extra"><br>
</div><div class="gmail_extra">    this() { impl = defaultImpl; }</div><div class="gmail_extra"><br></div><div class="gmail_extra">    int foo() { return 1; }     // pre-defined default behavior</div><div class="gmail_extra">
}<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">public Interface createPluggable()</div><div class="gmail_extra">{</div><div class="gmail_extra">    return new Pluggable().wrap!Interface;</div><div class="gmail_extra">
}</div><div class="gmail_extra">public Interface setPlugin(Interface i, Interface plugin)</div><div class="gmail_extra">{</div><div class="gmail_extra">    Pluggable p = enforce(i.unwrap!Pluggable);</div><div class="gmail_extra">
    p.impl = plugin ? plugin : Pluggable.defaultImpl;</div><div class="gmail_extra">    return i;</div><div class="gmail_extra">}</div><div class="gmail_extra"><br></div><div class="gmail_extra">// -------------</div><div class="gmail_extra">
// user side</div><div class="gmail_extra"><br></div><div class="gmail_extra">class Plugin : Interface</div><div class="gmail_extra">{</div><div class="gmail_extra">    override int foo() { return 10; }</div><div class="gmail_extra">
    override int bar() { return 20; }</div><div class="gmail_extra">}</div><div class="gmail_extra"><br></div><div class="gmail_extra">void main()</div><div class="gmail_extra">{</div><div class="gmail_extra">    import std.exception : assertThrown;</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">    Interface i = createPluggable();</div><div class="gmail_extra"><br></div><div class="gmail_extra">    assert(i.foo() == 1);</div><div class="gmail_extra">    assertThrown!NotImplementedError(i.bar());</div>
<div class="gmail_extra"><br></div><div class="gmail_extra">    i.setPlugin(new Plugin());  // set plug-in</div><div class="gmail_extra"><br></div><div class="gmail_extra">    assert(i.foo() == 1);</div><div class="gmail_extra">
    assert(i.bar() == 20);</div><div class="gmail_extra"><br></div><div class="gmail_extra">    i.setPlugin(null);          // remove plug-in</div><div class="gmail_extra"><br></div><div class="gmail_extra">    assert(i.foo() == 1);</div>
<div class="gmail_extra">    assertThrown!NotImplementedError(i.bar());</div><div class="gmail_extra">}</div><div><br></div><div>Kenji Hara</div></div></div>