お題
Math::PI
の値をファイル pi.txt に書き出してください。
コード
File.open("pi.txt", "w") do |f|
f.print Math::PI
end
改善
ファイルに書き出す専用のメソッド IO.write があります。
これを用いると
IO.write("pi.txt", Math::PI)
と簡素化できます。
IO.write
は File.write
とも書けます。これについては次節で述べます。
ファイル読み込みのほうも同様で,
text = nil
File.open("text.txt") do |f|
text = f.read
end
とか1
text = File.open("text.txt"){ |f| f.read }
などとしなくても,IO.read を使って
text = IO.read("text.txt")
と書けます。
IO.read
は File.read
とも書けます(次節参照)。
IO.write/IO.read か File.write/File.read か
IO.read
や IO.write
を使ったコードを RuboCop で検査すると,セキュリティーの観点から「IO.write
でなく File.write
を使う」ように言われます2。
というのは,File.read
や File.write
はファイルの読み書きしかできませんが,IO.read
や IO.write
はファイル以外のさまざまなものに対しても読み書きでき,第一引数に与えるものによってはコマンドの実行すらできてしまうからです。
例えば,
IO.read("| mkdir hoge")
とやると,ディレクトリーが作れてしまいます!3
よって,たとえばウェブアプリでユーザー入力に基づく値を第一引数に与えることはコマンドインジェクション攻撃に繋がり得ます。
そういう観点からすると,この記事の対象読者(初心者を想定)に IO.write
や IO.read
を勧めるのは良くない気もしますね。
File.write
や File.read
を使う,と覚えておいたほうがよいかもしれません。