std.algorithm.joiner unexpected behavior
Jonathan M Davis via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Aug 31 12:34:39 PDT 2017
On Thursday, August 31, 2017 18:43:40 Jesse Phillips via Digitalmars-d-learn
wrote:
> On Thursday, 31 August 2017 at 18:26:33 UTC, Sergei Degtiarev
>
> wrote:
> > Hi,
> > I tried to create a simple range concatenating several files,
> >
> > something like this:
> > File[] files;
> > ....
> > foreach(ln; joiner(files.map!(a => a.byLine)))
> >
> > writeln(ln);
> >
> > and I see every first line of each file is missing.
> >
> > However, when I do same thing with separator:
> > char[][] separator=["**** new file ****".dup];
> > foreach(ln; joiner(files.map!(a => a.byLine), separator))
> >
> > writeln(ln);
> >
> > everything works fine, both separator and first lines are
> > printed.
> > It looks pretty much as a bug for me, but I'm not sure I use it
> > correctly.
>
> Doesn't byLine() reuse a buffer, joiner probably caches the first
> line and calls .popFront()
In general, byLine does not work with other range-based algorithms precisely
because it reuses the buffer. I think that it does manage to work for some,
but IMHO, it should have just supported foreach via opApply and not been a
range at all. It's great for efficiency in a loop but horrible for range
chaining. Folks get bit by this problem all the time. Fortunately, we now
have byLineCopy which actually uses a separate dynamic array for each line,
but even still, often, someone grabs byLine and then gets weird behavior
that they don't understand.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list