なぜ File.read() でなくて IO.read() なのか? なぜ File.read() はあって File.write() はないのか?
Ruby 1.9.1 仕様変更締め切りを記念して、Ruby で前々から疑問に思ってたことを書いてみる。
- (1) IO.read() は、なぜ IO.read() であって File.read() でないのか。引数に filename を取るんだから、filename に関係ない IO より、関係のある File のほうに定義すべきだったのではないか。
- (2) IO.read() はあるのに、なぜ IO.write() がないのか。PHP にだって file_get_contents() と file_put_contents() があるというのに、Ruby で IO.write() がないというのは対称性に欠ける。
comp.lang.rubyで聞いてみたけど、あんまり納得のいく回答がなかった。
- IO.read() じゃなくて File.read() と書けるよ
- → そんなことはわかってるし、答えになってない
- File.read() を自分で定義したライブラリを用意すればいい
- → これも答えになってない
- File.write() は File.read() より dangerous だから用意されてないのさ
- → File.unlink() はもっと危険なのに用意されているぞ
- IO.write() は、ファイルの先頭から書くのか後ろに追加するのかとか、バイナリモードにするかどうかなど、オプションがたくさんあって複雑になるから用意されていない
- → IO.read() だって、後ろの N バイトだけを読むとか先頭の N バイトを読み飛ばすとか考えられるし、バイナリモードだってある。
- File オブジェクトには << 演算子が使えるぞ
- File.open(filename, 'w'){|f| f << str } を使えといってるなら、これも答えになってない
なんかこう、いろいろ理由をこじつけているけど、どれも納得できる理由にはほど遠い。つうかさ、知らないなら知らないって答えればいいのに、なんでこんなに変なこじつけを考えるんだろうね。
・・・と思っていたら、なんとまつもとさんが降臨!
I have questions about IO and File class. Why is IO.read(filename) defined? IMO, File.read() is more natural than IO.read() because IO class is not related to filename, I think. No big reason. Historically IO works on files, i.e. IO.open(path),
so that it was natural to provide these methods in IO too.
特に理由はないらしい。「IO works on files, i.e. IO.open(path)」の箇所はいまいち意味がわからないけど。
でもなあ、File#open(path) は filename を引数にとるけど、IO#open(fd) は file descriptor を引数にとるんだよな。
そう考えると、IO.open() が file descriptor ではなく filename を引数にとるのは違和感がある。
Is there any reason that IO.write() (or File.write()) is not provided? I have to define File.write() for each project... It is easy to define File.write() but I hope it is provided by Ruby. For File.read(), when you want to specify file mode, you can just say:
File.read(path, "rb")
For File.write(), it is more likely to be:
File.write(path, str, "wb")
which makes me feel weird. In 1.9, we can write
File.write(path, str, mode: "wb")
which I feel slightly better.
matz.
これは最初、Ruby1.9 では File.write(path, str, mode: "wb") というのが用意されるのか! ヤッター! ・・・と読んでしまったが、そうではなかった。
やっぱり Ruby1.9 でも File.write() は用意されないみたいだ。
Symbol#to_proc は導入されるくせに File.write() が用意されないなんて、なんか納得がいかない。