Max Samukha wrote: > On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep > <daniel.keep.li...@gmail.com> wrote: > >> >> Bill Baxter wrote: >>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep >>> <daniel.keep.li...@gmail.com> wrote: >>>> Frits van Bommel wrote: >>>>> Sean Kelly wrote: >>>>>> Daniel Keep wrote: >>>>>>> extern(C) void __identifier("blah$UNIX2003")(int); >>>>>> That would be awesome. >>>>>> >>>>>>> A beneficial side-effect is that I can finally get rid of all those >>>>>>> mixins that are just doing this: >>>>>>> >>>>>>> mixin(`void `~name_of_fn~`(int a) >>>>>>> { >>>>>>> // ... rest of function ... >>>>>>> }`); >>> I'm sure you've thought of this, so why can you not do >>> mixin(`void `~name_of_fn~`(int a) { implementation_of_function(a); }`); >>> or >>> mixin(`alias implementation_of_function `~name_of_fn~`); >> Simple enough to break: >> >> mixin(Property("foo", int)); >> mixin(Property("bar", float)); >> >> You can't use alias. You have to have some way of generating unique >> symbol names in a context you don't have any control over. > > As of 1.039, it seems to be possible to generate unique symbols in a > reasonable way (not well tested): > > template UniqueAlias(string member, string idName, int id = 0) > { > static if (is(typeof(mixin("this." ~ idName ~ ToString!(id))))) > mixin UniqueAlias!(member, idName, id + 1); > else > mixin("alias " ~ member ~ " " ~ idName ~ ToString!(id) ~ ";"); > } > > unittest > { > class A > { > int x; > } > > class B : A > { > int y; > void foo() {} > > template Bar() {} > > mixin UniqueAlias!("x", "m"); > mixin UniqueAlias!("y", "m"); > mixin UniqueAlias!("x", "m"); > mixin UniqueAlias!("foo", "m"); > mixin UniqueAlias!("Bar", "m"); > } > > auto s = new B; > s.m0 = 1; > s.m1 = 2; > assert(s.x == 1); > assert(s.y == 2); > assert(s.m2 == 1); > s.m3(); > alias B.m4!() bar; > } > >> There are also little issues with this like how the name of the function, >> when >> debugging, won't be what you expect it to be. >> >> No, you can't use templates because you can't mixin functions with >> non-public protection with templates. >> >> -- Daniel
Yes, this is definitely an improvement... char[] Foo(char[] name) { const char[] uid = createUniqueAlias(name); return `private void `~uid~`() { blah; }` ~ `private alias `~uid~` `~name~`;`; } class Bar { mixin(Foo("baz")); } Wait, no; that won't work. createUniqueAlias won't have access to the enclosing scope. I'll have to do this: char[] Foo(char[] name) { return ` mixin CreateUniqueAlias!("uid"); mixin("private void "~uid~"() { blah; }"); mixin("private alias "~uid~" `~name`;"); `; } class Bar { mixin(Foo("baz")); } Now I get TWO string-escaped mixins AND a meaninglessly named function mixed into my instantiating code's scope! Plus, since I need to refer to the unique name, I have to store it somewhere... and now THAT can collide with other symbols! I'm not saying it's not a neat trick; I've used the exact same thing a few times. But it's not a solution to *this* problem. -- Daniel