« Return to Thread: try-except in generator methods

Re: try-except in generator methods

by Daniel Grunwald :: Rate this Message:

Reply to Author | View in Thread

Avish wrote:
> Ok, so zip() and for() and everything else that uses IEnumerables
> should call dispose on them, that makes sense, but it's still valid
> for the "calling code" to only call MoveNext twice without disposing.
> So basically, we're talking about a "best effort" kind of support,
> where "as long as you use the language's builtin features, disposables
> are disposed correctly"?
>  
Yes. The "ensure" will be 'forgotten' if the enumeration is aborted
early without calling dispose.
If you don't dispose an enumerator, you can get problems just like if
you don't dispose any other disposable.

By the way, I just fixed TextReaderEnumerator.lines to dispose the
underlying TextReader.
Previously code such as:

    import System.IO
    for nr, line in enumerate(File.OpenText('test.txt')):
      print "${nr}: ${line}"
    File.Delete('test.txt')

would fail because the file was still in use until the garbage collector
finalized the StreamReader.
But there remains a problem with using TextReader like
IEnumerable<string>: a text reader can be enumerated only once.
Previously,

    import System.IO
    file = File.OpenText('test.txt')
    for nr, line in enumerate(file):
      print "${nr}: ${line}"
    for nr, line in enumerate(file):
      print "${nr}: ${line}"

would print the file only once, because the TextReader wasn't reset for
the second enumeration.
Now the code will fail with an ObjectDisposedException because the file
is closed at the end of the first loop.
I don't like this implicit TextReader->IEnumerable<string> conversion,
for easy file reading I would prefer a method like this:

    def readFile(filename as string):
      using reader = File.OpenText(filename):
        while (line = reader.ReadLine()) is not null:
          yield line

That would cause the file to be re-opened whenever GetEnumerator() is
called on the returned generator.

> Also, that reflected code made me realize we really need to typfiy our
> tuples and perhaps use string.Format() instead of newing up a
> StringBuilder on each string interpolation :)
>  
Typify tuples: yes!

string.Format: no, string.Format parses the format string and then calls
StringBuilder - so the current implementation is more efficient.
Since the number of items is known at compile time, even better would be
to simply use a single string.Concat call.

Daniel



signature.asc (193 bytes) Download Attachment

 « Return to Thread: try-except in generator methods