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.

Reply via email to