digitalmars.D.learn - Template/mixin ideas?
- Chris Katko (32/32) Oct 03 2018 I've got this simple task but I'm trying to perfect it as best I
- Sebastiaan Koppe (24/57) Oct 03 2018 A combination of static introspection with string mixins does the
- Chris Katko (6/31) Oct 03 2018 The mixin part wouldn't be slowed by strings, right? So the
- Sebastiaan Koppe (6/10) Oct 05 2018 During the concatenation phase you'll use an Appender. Afterwards
- Stanislav Blinov (4/5) Oct 05 2018 Since the purpose is terminal output, you could just make a
- Anonymouse (4/27) Oct 05 2018 https://run.dlang.io/gist/run-dlang/e0d0bcebe6c4edcc3cd0c2858183357d?com...
I've got this simple task but I'm trying to perfect it as best I can to learn something in the process. I have Linux terminal ASCII codes for coloring terminal output. string red(string) { /* ... */ } "Hello world".red => "\033[31mHello World\033[0m" which translates to "[red]Hello World[reset to normal text]". I have to do some slight trickery so I can chain them. But it all works fine. __The function is the same__ no matter what kind of color, bold, etc attribute I want. The only difference is the tag/prefix string. So I have a table (or enum): enum colors{ reset = "\033[0m", red = "\033[31m", bold = "\033[1m" //... } Absolute perfection would be some way to add a single line to that enum (or table) and magically get a new function. I add "blue" with its prefix code to the enum and immediately I can do: "hello world".blue Add yellow = "\033..." and I can do: "hello world".bold.yellow It's an interesting problem. Right now, I made a generic version that accepts the prefix code string directly called "color()" and red() translates to a call to color with the red string. blue() does the same. And so on. But it's still plenty of boiler plate. I do that so I don't have 80+ functions all a half-page long--which would be a nightmare to verify. It's surely nothing mission critical. But I wonder if I can distill this simple problem down further, I may be able to learn some tricks for later problems. Thanks.
Oct 03 2018
On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:I've got this simple task but I'm trying to perfect it as best I can to learn something in the process. I have Linux terminal ASCII codes for coloring terminal output. string red(string) { /* ... */ } "Hello world".red => "\033[31mHello World\033[0m" which translates to "[red]Hello World[reset to normal text]". I have to do some slight trickery so I can chain them. But it all works fine. __The function is the same__ no matter what kind of color, bold, etc attribute I want. The only difference is the tag/prefix string. So I have a table (or enum): enum colors{ reset = "\033[0m", red = "\033[31m", bold = "\033[1m" //... } Absolute perfection would be some way to add a single line to that enum (or table) and magically get a new function. I add "blue" with its prefix code to the enum and immediately I can do: "hello world".blue Add yellow = "\033..." and I can do: "hello world".bold.yellow It's an interesting problem. Right now, I made a generic version that accepts the prefix code string directly called "color()" and red() translates to a call to color with the red string. blue() does the same. And so on. But it's still plenty of boiler plate. I do that so I don't have 80+ functions all a half-page long--which would be a nightmare to verify. It's surely nothing mission critical. But I wonder if I can distill this simple problem down further, I may be able to learn some tricks for later problems. Thanks.A combination of static introspection with string mixins does the trick: --- enum colors { reset = "\033[0m", red = "\033[31m" } auto GenerateColorFuncs() { string result; static foreach(c; __traits(allMembers, colors)) result ~= "auto "~c~"(string str) { return colors."~c~" ~ str ~ colors.reset; }"; return result; } mixin(GenerateColorFuncs()); void main() { import std.stdio; writeln("bla".red); } --- Although you might want to replace the string concatenation with something more performant if used a lot.
Oct 03 2018
On Wednesday, 3 October 2018 at 11:51:01 UTC, Sebastiaan Koppe wrote:On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:The mixin part wouldn't be slowed by strings, right? So the "slowness" is the invokation part which changes strings and forces GC allocations, I guess? What's the alternative to using strings... for strings?[...]A combination of static introspection with string mixins does the trick: --- enum colors { reset = "\033[0m", red = "\033[31m" } auto GenerateColorFuncs() { string result; static foreach(c; __traits(allMembers, colors)) result ~= "auto "~c~"(string str) { return colors."~c~" ~ str ~ colors.reset; }"; return result; } mixin(GenerateColorFuncs()); void main() { import std.stdio; writeln("bla".red); } --- Although you might want to replace the string concatenation with something more performant if used a lot.
Oct 03 2018
On Thursday, 4 October 2018 at 01:12:04 UTC, Chris Katko wrote:The mixin part wouldn't be slowed by strings, right? So the "slowness" is the invokation part which changes strings and forces GC allocations, I guess?Yep, that is right.What's the alternative to using strings... for strings?During the concatenation phase you'll use an Appender. Afterwards you retrieve the resulting string from the appender. It is very similar to a StringBuilder in other languages. See std.array.appender
Oct 05 2018
On Thursday, 4 October 2018 at 01:12:04 UTC, Chris Katko wrote:What's the alternative to using strings... for strings?Since the purpose is terminal output, you could just make a custom formatter, something like this: https://run.dlang.io/is/F51UCZ
Oct 05 2018
On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:I've got this simple task but I'm trying to perfect it as best I can to learn something in the process. I have Linux terminal ASCII codes for coloring terminal output. string red(string) { /* ... */ } "Hello world".red => "\033[31mHello World\033[0m" which translates to "[red]Hello World[reset to normal text]". I have to do some slight trickery so I can chain them. But it all works fine. __The function is the same__ no matter what kind of color, bold, etc attribute I want. The only difference is the tag/prefix string. So I have a table (or enum): enum colors{ reset = "\033[0m", red = "\033[31m", bold = "\033[1m" //... } Absolute perfection would be some way to add a single line to that enum (or table) and magically get a new function. I add "blue" with its prefix code to the enum and immediately I can do: "hello world".blue Add yellow = "\033..." and I can do: "hello world".bold.yellowhttps://run.dlang.io/gist/run-dlang/e0d0bcebe6c4edcc3cd0c2858183357d?compiler=dmd https://issues.dlang.org/show_bug.cgi?id=19286 prevents us from using static foreaches to declare the aliases.
Oct 05 2018