Brad wrote:
> Given an array of structures that you need to populate.
> Also assume the structure is quite large and has many
> elements to fill in.
>
> S s[];
> while (something) {
>   s.length += 1;
>   auto sp = &s[$-1];   // method 1
>   sp.a = 1;
>   ...
>   with (s[$-1]) {   // method 2
>     a = 1;
>   }
>   ...
>   foreach (ref sp; s[$-1..$]) {  // method 3
>     sp.a = 1;
>   }
> }
>
> I don't mind 'with' statements, but they have a readability and
> maintenance problem if their scope is large.  The reader would have
> to be aware of the context of the structure and the local variables,
> whereas 'sp.a' is self documenting.
>
> method 3 is fine, and provides me with a reference to s[$-1],
> but I'd really like to have:
>    auto sp = ref s[$-1];  // possible method 4
> where sp is a reference, but no pointer arithmetic can be done on it.
>
> Another alternative would be runtime aliases.
>    alias s[$-1] as sp;
> Or
>    sp = with (s[$-1]); // I don't much like this syntax...
>
> In the meantime, I'll go with method 1.
>
>   -- Brad

I've been using a method in C++, which involves

    boost::shared_ptr
    boost::enable_from_shared
    boost::list_of

That was useful when objects had both some required and some optional properties. Anyway... If polymorphism is not needed something similar can be achieved very simply in D:

    S[] esses = [ S(42), S(100).optional(3) ];

The whole code:

import std.stdio;
import std.string;

struct S
{
    int must_have_;
    int optional_;

    this(int must_have)
    {
        must_have_ = must_have;
    }

    ref S optional(int optional_arg)
    {
        optional_ = optional_arg;
        return this;
    }

    string toString() const
    {
        return format("%s.%s", must_have_, optional_);
    }
}

void main()
{
    S[] esses = [ S(42), S(100).optional(3) ];
    writeln(esses);
}

Ali

Reply via email to