julia

Is it required to explicitly close a file inside a do-block in Julia?


I'm having a bit of difficultly understanding do blocks in Julia.

From the documentation:

The do x syntax creates an anonymous function with argument x and passes the anonymous function as the first argument to the "outer" function - map in this example.

This is a bit confusing, and I think the wording maybe misleading.

Here is some example code:

len = 1000000
v = rand(Int64, len)

open("example_data_vector.bin", "w") do ofile
    write(ofile, v)
    close(ofile) # required?
end

In this example code, it looks as if the returned value from open is stored in ofile. So, is the documentation incorrect?

I am not sure if the explicit close function call is required. If it is required, then I am not sure what the point of this do syntax is.


Solution

  • The documentation is correct. There is a form of open which takes a function as its first argument.

    The documentation for this can be found here:

    What the example code does is create an anonymous (lambda) function which looks a bit like this

    function (ofile)
        write(ofile, v)
        close(ofile)
    end
    

    and passes this as the first argument to open.

    However, the documentation states

    Apply the function f to the result of open(args...; kwargs...) and close the resulting file descriptor upon completion.

    therefore, the explicit call to close is not required.

    To make it explicitly clear, this

    open("example_data_vector.bin", "w") do ofile
        write(ofile, v)
    end
    

    is the same as this

    f = function (ofile)
        write(ofile, v)
    end
    
    open(f, "example_data_vector.bin", "w")
    

    which does the same as this

    ofile = open("example_data_vector.bin", "w")
    write(ofile, v)
    close(ofile)
    

    However, as noted by DNF below, the advantage and indeed purpose of the do block syntax is to provide an automatic mechanism for cleanup if something inside the block fails producing an error.