Given some #open() and #close() methods, you can define trivially
def open_block(fn)
fh = open(fn)
yield fh
close(fh)
end
which accepts a block, passes the file handler corresponding to a given filename and closes it when done (you'd normally use an ensure clause, but the original message carried the above definition). This is a standard idiom. Now, given a working #open_block, can you define #open and #close?
As I read that, I knew it would involve callcc. #open was trivial, #close seemed harder. Actually hard enough to deserve being done. I was game.
It was pretty late (~1AM), but callcc is always fun and anyway it would only take a few minutes to solve, so I quickly came up with
def _open(name); puts "open: #{name}"; "IO<#{name}>" end
def _close(name); puts "close: #{name}" end
def open_block(fn); fh = _open(fn); yield fh; _close(fh); end
open_block("hoge"){|x| puts "Got #{x}" }
def open(x)
callcc do |cc|
r = nil
open_block(x) do |fh|
r = callcc do |cc2|
fh.instance_variable_set("@_closecc", cc2)
cc.call(fh)
end
end
r.call
end
end
def close(x)
callcc do |cc|
x.instance_variable_get("@_closecc").call(cc)
end
end
a = open("foo")
puts "----"
close(a)
puts "end"