January 25

On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote:

>

On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:

>
struct Person {
    string name, email;
    ulong age;
}
Person a{"n","email",33};

C++ can achieve ultimate simplicity without violating DRY,
And here, D violates the DRY principle!
Moreover, as the package level, module level, class level, member level, D language violates integrity.
Because D has no class level limit.
These are all not serious states.

You know you can use struct literals in initializers, right?

import std.stdio;
struct Person {
    string name, email;
    ulong age;
}

void main() {
    Person p = {name: "Joe", email: "joe@example.com", age: 30};
    writeln(p);
}
January 25

On Thursday, 25 January 2024 at 08:46:34 UTC, Renato wrote:

void main() {
    Person p = { "Joe", "joe@ab.com", 30};
    writeln(p);
}

I just tested it and it works. It's great!

February 01

On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:

>
import std;

struct Person {
    string name, email;
    ulong age;
    auto withName(string name) { this.name=name; return this; }
    auto withEmail(string email) { this.email=email; return this; }
    auto withAge(ulong age) { this.age=age; return this; }
}

void main() {
    Person p;
    p.withName("Tom").withEmail("joelcnz@gmail.com").withAge(44);
    writeln(p);
}

I had reason to need this to work a while ago and opDispatch came in very handy. I was able to cook up one that forwarded calls to other members in a struct, while returning this by ref, allowing for chaining calls. I use it with UDAs.

(Scroll to the unit tests for examples.)

/++
    Mixin template generating an `opDispatch` redirecting calls to members whose
    names match the passed variable string but with an underscore prepended.
 +/
mixin template UnderscoreOpDispatcher()
{
    ref auto opDispatch(string var, T)(T value)
    {
        import std.traits : isArray, isAssociativeArray, isSomeString;

        enum realVar = '_' ~ var;
        alias V = typeof(mixin(realVar));

        static if (isAssociativeArray!V)
        {
            // Doesn't work with AAs without library solutions
        }
        else static if (isArray!V && !isSomeString!V)
        {
            mixin(realVar) ~= value;
        }
        else
        {
            mixin(realVar) = value;
        }

        return this;
    }

    auto opDispatch(string var)() inout
    {
        enum realVar = '_' ~ var;
        return mixin(realVar);
    }
}

///
unittest
{
    struct Foo
    {
        int _i;
        string _s;
        bool _b;
        string[] _add;
        alias wordList = _add;

        mixin UnderscoreOpDispatcher;
    }

    Foo f;
    f.i = 42;         // f.opDispatch!"i"(42);
    f.s = "hello";    // f.opDispatch!"s"("hello");
    f.b = true;       // f.opDispatch!"b"(true);
    f.add("hello");   // f.opDispatch!"add"("hello");
    f.add("world");   // f.opDispatch!"add"("world");

    assert(f.i == 42);
    assert(f.s == "hello");
    assert(f.b);
    assert(f.wordList == [ "hello", "world" ]);

    auto f2 = Foo()
        .i(9001)
        .s("world")
        .b(false)
        .add("hello")
        .add("world");

    assert(f2.i == 9001);
    assert(f2.s == "world");
    assert(!f2.b);
    assert(f2.wordList == [ "hello", "world" ]);
}

You could trivially adapt it to use a withName, withEmail calling scheme instead of the underscore thing.

May 14

On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote:

>

On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote:

>

[...]

Nonetheless, this usually used with Objects (new class/struct instances), like so:

import std;

[...]

Fluent Interface 😀

1 2 3
Next ›   Last »