On Thursday, 12 May 2016 at 13:43:10 UTC, thedeemon wrote:
On Thursday, 12 May 2016 at 10:17:19 UTC, xtreak wrote:
Thanks a lot. Can you kindly elaborate a little more on
File.byLine with an example of the scenario so that I don't
get bitten by it. File.byLine.array works as expected for me.
A little more explanation on the permutations will also be
helpful since joiner.map!array converts the subranges to
arrays, so does joiner work by mutating state if so how does
it do.
With some ranges the value they return by .front is only valid
until the next call to popFront(). For example, File.byLine()
reuses its buffer so after popFront() is called the buffer
contains different data and if you had references to the
contents of previously returned value they become invalid. This
is why byLineCopy() was added. In the same vein permutations()
returns a range that has a mutable array of indices inside,
which changes every time popFront() is called, and since every
value returned by its .front refers to that indices array, if
you collect such permutations they will all use the same array
of indices and show the same order of elements, the same
permutation.
Because of this mutable nature of some ranges it's important to
understand in which order calls to .front and .popFront()
happen. The array() function calls popFront on its input in a
loop, consuming the mutable ranges, while map() does not. So in
r.map!f.array
function f will receive different valid values, before they get
invalidated in the loop of array(). But if they contain
references to something mutable, it makes sense to make copies
before the thing they refer to mutates.
Thanks a lot for the info that really clears a lot of things for
me :) I see from the source that byLineCopy makes a .dup on each
line and cached at
https://github.com/dlang/phobos/blob/master/std/stdio.d#L2029-L2034 with gotFront when front is called a lot of times. I could see a function called emplaceref being used in array. Any ideas on that please.