Schroedinger's Ranges

vacuum_tube jxl.ppg at gmail.com
Thu Jun 3 00:39:04 UTC 2021


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!


More information about the Digitalmars-d-learn mailing list