On Mon, 01 Mar 2010 16:51:41 -0500, Lars T. Kyllingstad
<[email protected]> wrote:
Paul D. Anderson wrote:
I've entered this as a Phobos bug, but wanted to be sure I was
understanding this properly (i.e., this is a bug, right?):
From the description of the put primitive in std.range:
"r.put(e) puts e in the range (in a range-dependent manner) and
advances to the popFront position in the range. Successive calls to
r.put add elements to the range. put may throw to signal failure."
From the example of std.array for the put function:
void main()
{
int[] a = [ 1, 2, 3 ];
int[] b = a;
a.put(5);
assert(a == [ 2, 3 ]);
assert(b == [ 5, 2, 3 ]);
}
So, "putting" 5 into the array a removes the first element in a, and
changes the value of the first element of b. I would expect the first
assert in the code above to read:
assert(a == [ 5, 1, 2, 3 ]);
The implementation of std.array.put doesn't make sense: void put(T,
E)(ref T[] a, E e) { assert(a.length); a[0] = e; a = a[1 .. $]; }
It modifies a[0] and then replaces the array with the tail of the
array,
omitting the first element.
It's possible there is some arcane meaning to the word "put" that I'm
not aware of, but if it means "insert an element at the front of the
range" then std.array.put is wrongly implemented.
Paul
I don't think it's a bug, I think it's just that arrays aren't that
useful as output ranges. It has to be defined that way for it to adhere
to the range interface conventions. (Think of the array as a file
instead, then it makes more sense.) You just have to keep a backup
slice of the entire array so you can access the elements you have put()
later:
int[] a = [0, 0, 0, 0, 0, 0];
int[] aSlice = a[];
foreach (i; 0 .. a.length) aSlice.put(i);
assert (a == [0, 1, 2, 3, 4, 5]);
-Lars
Yes, it's not a bug. If you think of a common usage of arrays (buffers)
this makes perfect sense. And if you want the other behavior you're
supposed to use the appender wrapper.