[your code here]

bearophile bearophileHUGS at lycos.com
Sun Jan 15 07:15:55 PST 2012


Jos van Uden:

> still learning this stuff, feel free to correct or improve

Next time I suggest you to use D.learn.

This is a first draft with some changes:

import std.traits, std.string, std.ascii, std.conv, std.range;

// is partial application better here?
dstring rot13(C)(immutable(C[]) s) pure /*nothrow*/
if (isSomeChar!C) {
    return rot(s, 13);
}

// or maybe just use in int key=13 as default argument
// is it right to use a signed int for key?
dstring rot(C)(immutable(C[]) s, in int key) pure /*nothrow*/
if (isSomeChar!C)
in {
    // preconditions here...
    // only ASCII input chars?
    // Are std.ascii.isUpper / isLower working with UTF?
} out(result) {
    // don't use .length here unless the input is verified to contain
    // no past ASCII chars
    assert(walkLength(s) == walkLength(result));
} body {
    auto result = new dchar[s.length];

    foreach (i, dchar c; s) { // not nothrow
        // reassigning c here is not nice
        if (isLower(c))
            result[i] = ((c - 'a' + key) % 26 + 'a');
        else if (isUpper(c))
            result[i] = ((c - 'A' + key) % 26 + 'A');
    }

     return result; // implicit cast, but only dstring output.
     // Otherwise allocate a result with alloca() and copy
     // it at the end with to!S(result)
} unittest {
    // unit tests here...
}

void main() {
    import std.stdio;
    writeln(rot13("hello"));
}

Your little program also shows some of the current D2 problems. You need care to catch a function signature like that that allows implicit cast of the result of the pure function.

Bye,
bearophile


More information about the Digitalmars-d mailing list