On 11/20/2016 04:34 AM, Charles Hixson via Digitalmars-d-learn wrote:
Whether you would call the change "break things for your code" might be
dubious. It would be effectively broken, even if technically my code
was doing the correct thing. But my code wouldn't be storing the data
that needed storing, so effectively it would be broken.
I don't see how it's dubious. It's an error by the user. When users are
given a dynamic array (and not by reference), they cannot expect that
your code sees changes to length. That's just not how arrays work. When
a user has that wrong expectation, and writes wrong code because of it,
then it's arguably their own fault. However, if you want you can hold
their hand a bit and make the mistake less likely.
"Write something
for yourself" is what I'd like to do, given that the language doesn't
have that built-in support, but I can't see how to do it.
Wrap the array in a struct that has indexing, but doesn't allow setting
the length or appending. Here's a quick prototype:
----
struct ConstLengthArray(E)
{
private E[] data;
this(E[] arr) { this.data = arr; }
ref inout(E) opIndex(size_t i) inout { return data[i]; }
@property size_t length() const { return data.length; }
}
void main()
{
auto cla = ConstLengthArray!ubyte([1, 2, 3, 4, 5]);
/* Mutating elements is allowed: */
cla[0] = 10;
assert(cla[0] == 10);
/* No setting length, no appending: */
static assert(!__traits(compiles, cla.length = 3));
static assert(!__traits(compiles, cla ~= 6));
}
----
You might want to add support for slicing, concatenation, etc. Maybe
allow implicit conversion to const(E[]), though that would also allow
conversion to const(E)[] and that has a settable length again.