Hacker News new | past | comments | ask | show | jobs | submit login

I believe c# has something similar too, "using"

  using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None))
  {
      Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
      // Add some information to the file.
      fs.Write(info, 0, info.Length);
  }



I was about to put this down. Although, the C# world requires an IDisposable interface and implies that you're operating on a resource.

Ruby has similar concept when you open a file and pass in a block to operate on the File object.

I'm pretty sure the author is just excited about the language and failed to recognize that this pattern is everywhere in different programming languages.


The author is excited that functions have their inverses by default, I think. Analogous construct in Python would be somethoug like:

  with_under do_something() as f:
    ...
translated to

  f = do_something()
  ...
  f.undo_something()
With do_something automatically matched to undo_something.


You can do the same thing in C# that you can in Ruby

    new FileEx (SOME_PATH, () => ConsoleEx.ReadLine (), () => ConsoleEx.CurrentLine != "QUIT").WriteAll ();
is equivalent to

    using (var file = new File(SOME_PATH))
    {
        string line = null;

        try
        {
             while((line = Console.ReadLine) != "QUIT")
             {
                file.WriteLine(line);
             }
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            sw.Close();
        }
    }


For a second I was intrigued and tried to find that FileEx class that I obviously missed to notice before.

It doesn't seem to be part of the framework though? Homegrown and _you_ expand it to something that is equivalent to the second code snippet?


Yes, it is homegrown[1]. I have quite a few little utilities that use (or abuse) iterators to get something like RAII in C# (I don't like relying on using/IDisposable and I especially don't like requiring it in my public types).

Another one that I use a lot [2]:

    SqlCommandEx sql = "select * from person";

    foreach (dynamic result in sql)
    {
        var full_name = result.first_name + " " + result.last_name;

        DateTime dob = result.dob;
         //do other stuff

    } //connection automatically disposed.
[1] Relevant source: http://pastebin.com/LwHD8MHc

[2] https://github.com/noblethrasher/Prelude/blob/master/SQL.cs


I'm going to assume I missed something, because from what I'm reading:

1. You're avoiding IDisposable for reasons you don't explain and I fail to see

2. You replace it with an idiom which is supposed to do the same thing (except abusing iterators instead of using tools dedicated to that job) and which I don't believe works, as your connection will not (as far as I can see) be disposed of if there's an error in the foreach block. And the code you linked does not seem to use this "pattern" anywhere


Avoiding using/IDisposable is taste thing; I'm not saying that anyone else should do it.

If called from the `foreach` statement, the code in a finally block of an iterator is guaranteed to execute even if the loop exits early due to a `break` or exception. The compiler will also generate a call to Dispose() as well.

Also, it's not really an abuse. When dealing with an unmanaged resource, you're almost always either pulling a stream of data out or pushing a stream of data in. That's precisely the use case of IEnumerable and its dual, IObservable (SqlCommandEx is an example of IEnumerable and FileEx is a loose example of IObservable).

P.S. Now there might be a thus far undiscovered bug in my SqlCommandEx code to which I linked (e.g. the compiler only generates calls to Dispose() on IEnumerator<T> which might not work for dynamic types, I haven't checked) but it's possible to do what I described in principle.


Yes, you can do this but I usually just end up using the helper functions i.e

      System.IO.File.AppendAllText(path, "This is some text in the file.");
Also, why are you writing text to binary file instead of just writing the text as a text file?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: