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