From: matz@... (Yukihiro Matsumoto) Date: 2003-04-14T01:30:32+09:00 Subject: [ruby-dev:20018] Re: shim/ruby16/tests まつもと ゆきひろです In message "[ruby-dev:20013] Re: shim/ruby16/tests" on 03/04/12, Tanaka Akira writes: |> 私自身はこれで不自然ではないと思いますが、どう思いますか? | |とすると、 | |% ruby -e 'File.open("/dev/null") {|f| IO.new(f.fileno).close }' | |というように、ブロック中で file descriptor が close されたときに |IOError にならないのは不自然ではないんでしょうか。 えーと、これは独立した問題ではないでしょうか。 元々の問題は open(path){|f| f.close} は f = open(path) begin f.close ensure f.close end となるので、 f = open(path) f.close f.close という実行順序になって例外を発生すると解釈できるので不自然で はないのではないかという趣旨です。 一方、田中さんが指摘しているのは File.open("/dev/null") {|f| IO.new(f.fileno).close } ですから、つまり f = open("/dev/null") IO.new(f.fileno).close f.close という実行順序になり、そもそもこれは例外を発生しないので同じ 条件ではないと思います。これが例外を発生させないが不自然では ないか、というのは意味のある言明だとは思いますが、少なくとも 独立でしょう。 --- で、元の問題に戻ると、二重closeで例外を発生させない方が親切 ではあるが、一方、隠された挙動が増えることになり、正確な説明 がややこしくなるような気もするので、一概に親切な方が良いとも 言いきれないので、決めかねています。 また、田中さんの問題については、同じfile descriptorが複数の IOから参照される可能性があるということは、きちんとRuby全体で file decriptorの参照管理を(リファレンスカウントのようなこと をして)行う必要があるだろうな、と昔から考えてはいます。stdio を捨てるときに一緒にやろうか、と漠然と考えていたのですが。 まつもと ゆきひろ /:|)