Page 1 of 1

Making StreamReader Iterable

PostPosted: Sun Jan 26, 2014 8:44 pm
by oahmad04
I tried to make StreamReader iterable with the following:
extend StreamReader
"""Makes StreamReader iterable (by line)"""

cue enumerate as String*
"""Yields each line in the open file"""

test

# Make and test a file:

File.writeAllText("Source", "line 1\nline 2\nline 3")
lines = []

using file = File.openText("Source")
for line in file, lines.append(line)

assert lines == ["line 1\n", "line 2\n", "line 3"]

File.delete("Source")

# Make and test an empty file:

File.writeAllText("Source", "")
lines = []

using file = File.openText("Source")
for line in file, lines.append(line)

assert lines == []

File.delete("Source")

body

while true
line = .readLine
if line is nil, break
yield line to !

I get the following errors:

Code: Select all
iterateFile.cobra(23): error: Cannot infer the type for "line" from the "for" loop.
iterateFile.cobra(35): error: Cannot infer the type for "line" from the "for" loop.


What did I do wrong? Thanks.

Re: Making StreamReader Iterable

PostPosted: Sun Jan 26, 2014 9:01 pm
by Charles
Part of being enumerable to a "for" loop is implementing IEnumerable. You cannot make this happen to an existing class (by using extend or any other technique).

Note that .NET 4 introduced File.readLines which basically does what you're looking for:
http://msdn.microsoft.com/en-us/library ... 3(v=vs.110).aspx

If you still wanted to put something on a reader, and you don't mind slapping a method on the reader in the for loop, then you could do something like this:

extend TextReader

def readLines as String*
...

...

for line in tr.readLines, print line

Note that other possibilities for looping through a reader include characters, words and regex matches. For this reason, I would actually prefer this form over making the reader directly enumerable.

Re: Making StreamReader Iterable

PostPosted: Sun Jan 26, 2014 9:02 pm
by Charles
Also, in Cobra tests, it is customary to use StringWriter and StringReader in place of actual file I/O. The tests will run faster, have less side effects on the machine and less of a chance of failing for external reasons (permissions, etc.).

Re: Making StreamReader Iterable

PostPosted: Sun Jan 26, 2014 10:00 pm
by oahmad04
Thanks for your response. I thought it would be like Python where you just add a "def __iter__" method and it works. Now I know.

Charles wrote:Note that other possibilities for looping through a reader include characters, words and regex matches. For this reason, I would actually prefer this form over making the reader directly enumerable.


Good point. I was missing the Python syntax. I should probably just use what's given with Cobra instead of trying to make working with files more like Python.

Charles wrote:Note that .NET 4 introduced File.readLines which basically does what you're looking for:
http://msdn.microsoft.com/en-us/library ... 3(v=vs.110).aspx


I saw this actually. Very handy. I was just worried it wouldn't work with huge files. I don't actually have any huge files in mind. I'm not working on any projects. I'm just learning Cobra by making little namespaces I think will be useful.

Re: Making StreamReader Iterable

PostPosted: Sun Jan 26, 2014 10:06 pm
by oahmad04
I saw this actually. Very handy. I was just worried it wouldn't work with huge files. I don't actually have any huge files in mind. I'm not working on any projects. I'm just learning Cobra by making little namespaces I think will be useful.

Oh, I haven't seen this. I thought you posted a link to readAllLines. This is cool.