Lisp-y recursion comes in pretty handy in this case:
Main> openall(f::Function, file::AbstractString, other_files...) =
openall(f, (file, "r"), other_files...)
openall (generic function with 1 method)
Main> function openall(f::Function, file::Tuple, other_files...)
open(file...) do handle
openall(other_files...) do handles...
f(handle, handles...)
end
end
end
openall (generic function with 2 methods)
Main> openall(f::Function) = f()
openall (generic function with 3 methods)
Main> openall("f1") do f1
@show f1
end
f1 = IOStream(<file f1>)
IOStream(<file f1>)
Main> openall("f1", ("f2", "w")) do f1, f2
@show f1 f2
end
f1 = IOStream(<file f1>)
f2 = IOStream(<file f2>)
IOStream(<file f2>)
Main> openall("f1", ("f2", "a"), "f3", ("f4", "w")) do f1, f2, f3, f4
@show f1 f2 f3 f4
end
f1 = IOStream(<file f1>)
f2 = IOStream(<file f2>)
f3 = IOStream(<file f3>)
f4 = IOStream(<file f4>)
IOStream(<file f4>)
Nice. What I like about the f(x)! syntax is that code that works with the exclamation mark at the end of the function will (most of the time?) work without it as well, making this syntax flexible and forgiving and therefore easier to adopt.
Ah, yes, I remember this discussion from a while ago now. Has anyone picked up implementing the ()! construct?
In another thread I am busy with trying to figure out how to make a python-style generator that produces IO objects. The idea would be that the generator creates and opens the IO, and the caller/consumer uses the object until the next item. Then when the caller is done with the object, the GC should come in and trigger a close() on the IO object. (If this would be the mechanism, the GC should probably also be triggered by a low-on-filedescriptors event).