I've been trying to make a struct for CSV parsing and manipulating. The code was as follows:
```
struct CSVData(bool HeaderFromFirstLine)
{
        char[][] header = [];
        char[][][] rest = [];

        this(string filename)
        {
                auto tmp = File(filename).byLine();
                
                if(HeaderFromFirstLine)
                {
                        this.header = CSVData.parseCSV(tmp.front()).array;
                        tmp.popFront();
                }

                this.rest = tmp.map!(e => parseCSV(e)).array;
        }

        static char[][] parseCSV(char[] str)
        {
                char[][] tmp = split(str, ",");
                return tmp;
        }
        
        void print()
        {
                writeln(this.header);
                foreach(e; this.text)
                        writeln(e);
        }
}

void main()
{
        auto data = CSVData!true("testdata");
        data.print();
}
```
The "testdata" text file looked like this:
```
10,15,Hello world
stuff,,more stuff
```
And the output from running it looked like this:
```
["st", "ff", ",more stuff"]
["stuff", "", "more stuff"]
```
As you can see, the `header` field is not printing correctly. In an attempt to debug, I added several `writeln`s to the constructor:
```
this(string filename)
{
        auto tmp = File(filename).byLine();
        
        if(HeaderFromFirstLine)
        {
                this.header = CSVData.parseCSV(tmp.front()).array;
                tmp.popFront();
                writeln(this.header);
        }

        this.text = tmp.map!(e => parseCSV(e)).array;
        writeln(this.header);
}
```
This produced the following output:
```
["10", "15", "Hello world"]
["st", "ff", ",more stuff"]
["st", "ff", ",more stuff"]
["stuff", "", "more stuff"]
```
I then tried commenting out the offending line (the one with the `map`) and got the expected result:
```
["10", "15", "Hello world"]
["10", "15", "Hello world"]
["10", "15", "Hello world"]
```
Finally, I replaced the offending line and called a different function on `tmp`:
```
writeln(tmp.front);
```
And got the following result:
```
["10", "15", "Hello world"]
stuff,,more stuff
["st", "ff", ",more stuff"]
["st", "ff", ",more stuff"]
```
So it appears that observing or modifying `tmp` somehow modifies `header`, despite not interacting with it in any visible way.

What is the reason for this? I'm guessing it either has to do with the internals of ranges, or that the arrays were messing up somehow, but I'm not sure.

Thanks in advance!

Reply via email to