On Monday, 11 March 2019 at 15:23:53 UTC, HaraldZealot wrote:
```d
File[] files;
foreach(filename; args[1 .. $])
{
    files ~= File(filename, "r");
}

auto ranges = files.map!(a => a.byLineCopy);

writeln(ranges[0].front);
writeln(ranges[0].front);
writeln(ranges[0].front);
```
produces
```
1
2
3
```
[...]
What I'm doing wrong with `map`? Or is this a bug?

`map` is lazy in the sense that it (re-)evaluates the given function whenever you access an element. That means you're calling `byLineCopy` three times on the same file. Your code effectively does this:

    writeln(files[0].byLineCopy.front);
    writeln(files[0].byLineCopy.front);
    writeln(files[0].byLineCopy.front);

The range created by `byLineCopy` immediately reads a line from the file to populate its `front`. So you're reading three lines from the file.

Strictly speaking, I don't think any of this qualifies as a bug. `map`'s behavior might be surprising, but it's deliberate, as far as I know.

To avoid the re-evaluation, assign `ranges[0]` to a variable before using it:

    auto lines = ranges[0];
    writeln(lines.front);
    writeln(lines.front);
    writeln(lines.front);

That should print the same line three times.

Reply via email to