Please bear with my ignorance I'm new to D, but why is that any
better compared to a simple
switch(key){
default: throw Exception("Invalid attribute '%s'".format(key));
case "name": d.name = value;
break;
...
...
}
On Friday, 20 April 2012 at 04:05:43 UTC, H. S. Teoh wrote:
I'm writing some code that does some very simplistic parsing,
and I'm
just totally geeking out on how awesome D is for writing such
code:
import std.conv;
import std.regex;
import std.stdio;
struct Data {
string name;
string phone;
int age;
... // a whole bunch of other stuff
}
void main() {
Data d;
foreach (line; stdin.byLine()) {
auto m = match(line, "(\w+)\s+(\w+)");
if (!m) continue;
auto key = m.captures[1];
auto value = m.captures[2];
alias void delegate(string key, string value) attrDg;
attrDg[string] dgs = [
"name": delegate(string key, string value) {
d.name = value;
},
"phone": delegate(string key, string value) {
d.phone = value;
},
"age": delegate(string key, string value) {
d.age = to!int(value);
},
... // whole bunch of other stuff to
// parse different attributes
];
attrDg errordg = delegate(string key, string value) {
throw Exception("Invalid attribute '%s'"
.format(key));
};
// This is pure awesomeness:
dgs.get(key.idup, errordg)(key.idup, value.idup);
}
// ... do something with Data
}
Basically, I use std.regex to extract keywords from the input,
then use
an AA to map keywords to code that implement said keyword.
That AA of
delegates is just pure awesomeness. AA.get's default value
parameter
lets you process keywords and handle errors with a single AA
lookup. I
mean, this is even better than Perl for this kind of
text-processing
code!
The only complaint is that I couldn't write auto[string] dgs
and have
the compiler auto-infer the delegate type. :-) Additionally, I
wasn't
sure if I could omit the "delegate(string,string)" after each
keyword;
if that's actually allowed, then this would make D totally pwn
Perl!!
(I left out some stuff that makes this code even more of a joy
to write:
using nested try/catch blocks, I can throw exceptions from
deep-down
parsing code and have the loop that loops over input lines
automatically
prefix error messages with the filename/line number where the
error
occurred. This way, even errors thrown by to!int() will be
formatted
nicely. With Perl, this gets extremely messy due to its
pathological use
of $. for line numbers which can get overwritten in unexpected
places if
you're processing more than one file at a time.)
Did I mention I'm totally in love with D?? Seriously. It can
handle
system-level code and "high-level" text-processing code with
total
impunity. What's there not to like?!
T