What's the best idiom here?

Hello all

I have a project in which I am using variables to represent sets of local state. For example:

locf = LocalFile("/tmp/myfile")

I then want to give the user the opportunity to delete these bits of state via the API, so I have a function

function delete_file!(l::LocalFile)

The issue I’m having here - which might be a programming one or might be a conceptual one - is what to do with this variable when I delete the file. I was originally thinking to just set it to nothing, but I’m not actually sure that this is possible - it seems that you can mutate function parameters but not entirely re-assign them. A clear! function seems like it might have been appropriate but is no longer part of the language. Any suggestions much appreciated.

Why do you want to delete the variable in the first place? It’s just a string, not the whole file as saved on disk. Once locf goes out of scope, the garbage collector will free the memory on its own.

Is there some more context that would be helpful here?

The thinking is that it then makes it clear to the user that the underlying resource (in this case, the file) is no longer present. For example, running delete_file! again twice on the same variable would generate an error second time around, which is nice and clear.

If you use rm, it will already error when the given file doesn’t exist:

julia> rm("this_file_does_not_exist")                                                 
ERROR: IOError: unlink("this_file_does_not_exist"): no such file or directory (ENOENT)

In general, “unbinding” a variable is not possible.

Yes, that works reasonably well in that example (a local file). It’s still possible that the user may view the LocalFile struct in the interim, though, and not realize that it’s no longer valid. Ideally I think I would set it to nothing, but it seems like this isn’t possible. Thanks though.

If you want to communicate to the user that they have already deleted the file, you can check for the existence explicitly with isfile or save that information as part of the struct.

If you’re concerned with persistent bindings in the REPL, I recommend putting more things into functions (which clean up their local variables after execution) and not having the variables linger in global scope in the first place.

Do you mean something like this?

function delete_file!(l::LocalFile)
    isempty(l.path) && error("File has already been deleted")
    l.path = ""
1 Like