From: Matt Armstrong Date: 2002-03-07T07:20:33+09:00 Subject: Re: exception-safety and opening sockets Paul Brannan writes: > When I open a file and want to make sure a file gets closed, even when I > get an exception, I do: > > File.open("filename") do |io| > puts io.gets > raise RuntimeError > end > > I tried doing the same thing with a socket: [...] > but I get no output. The closest I can get is: > > socket = TCPSocket.new("hostname", "portname") > begin > puts "here" > puts socket.gets > raise RuntimeError > ensure > socket.shutdown > end You can also do this to avoid putting "socket" in the outer scope. begin socket = TCPSocket.new(...) puts socket.gets ensure socket.shutdown if socket end If TCPSocket.new throws an exception, socket will just be nil. And if you're doing the socket operation in a method, this works too: def do_something_with_socket # you can put a bunch of code here socket = TCPSocket.new(...) # use the socket here ensure socket.shutdown if socket end > However, socket is still in scope, but is already closed, which is > not desirable. Is there a method in Ruby that does something > similar to: > > def safe_socket_open(host, port) > socket = TCPSocket.new(host, port) > begin > yield socket > ensure > socket.shutdown > end > end You just wrote it. :-) -- matt