Posted at

Ruby の FileTest.directory? だけでファイルかディレクトリかを判定してはダメ

More than 1 year has passed since last update.


なぜ

Ruby で対象がファイルなのかディレクトリなのかを調べるときに FileTest.directory?FileTest.file? を使うと思いますが、これらをこんなふうに使うとバグのもとになります。

path = '/hoge/fuga'

if FileTest.directory? path
# ディレクトリのときの処理
else
# ファイルのときの処理
end

なぜなら、これらのメソッドは、パスが存在しないときやシステムコールに失敗したときも false を返すからです。

この例だと、本来はディレクトリであるのにファイルシステムの不具合等でシステムコールに失敗し、ファイルであるとして設計している else 節の処理が実行され、ファイルサイズの取得などで予期せぬ不具合が起きるといったようなことになってしまいます。


対策

対象がファイルなのかディレクトリなのか確実に判定するためには、必ず FileTest.directory?FileTest.file? の両方を使用し、万一どちらでもないと判定されてしまった場合は例外を発生させるのがよいと思います。

path = '/hoge/fuga'

if FileTest.directory? path
# ディレクトリのときの処理
elsif FileTest.file? path
# ファイルのときの処理
else
raise 'ファイルでもディレクトリでもないなんてあり得ない!'
end


参考

ちゃんとドキュメントを読みましょうっていう話なんですけどね :sweat_smile:


そうでない場合、ファイルが存在しない場合、あるいはシステムコールに失敗した場合などには false を返します。