はじめに
こんにちは!アメリカの大学で語学を学びながら、独学でソフトウェアエンジニアを目指している者です。
今回はコードを通してDir.globについてまとめていきたいと思います。
たのしいRubyという教材で現在Dir
クラスについて勉強しているのですが、前回書いた再帰呼び出しを使わないでディレクトリ探索ができるコードがあったので、Dir.glob
の説明と合わせてそれについても触れていきたいと思います。
Dir.glob
とは?
Dir.glob
は、指定したパターンに一致するファイルやディレクトリを効率よく取得できるRubyのメソッドです。以下のように簡単に使えます
Dir.glob("*.rb")
# カレントディレクトリ内のすべての Ruby ファイルを取得
取得結果は 配列 で返されるため、結果を手軽に操作できます。また、ブロックを渡すと1件ずつ順次処理できる点も特徴です。
パターン指定の柔軟性について
Dir.glob
の最大の魅力は、柔軟なパターン指定が可能な点です。以下に代表的な例を挙げます。
パターン | 説明 |
---|---|
"*" |
カレントディレクトリ内のすべてのファイルやディレクトリを取得 |
"*.rb" |
.rb 拡張子を持つファイルを取得 |
"*.{rb,py}" |
.rb または .py 拡張子を持つファイルを取得 |
["*.rb", "*.py"] |
.rb と .py 拡張子を持つファイルを両方取得 |
"**/*" |
サブディレクトリを含むすべてのファイルを再帰的に取得 |
"**/.*" |
サブディレクトリを含む隠しファイル(. から始まるファイル)を取得 |
詳細はリファレンスマニュアルをご覧ください
また、Dir.glob
のパターン指定は「ワイルドカード」を用いますが、正規表現とは異なります。以下の点が特に重要です。
-
ワイルドカードの
*
任意の文字列にマッチします。また、単独で使うと カレントディレクトリ を意味します。 -
正規表現の
*
直前の部分式を 0回以上繰り返す という特定の条件を意味します。
再帰呼び出しコードとの比較
今回は前回の記事で書いた再帰呼び出しのコードと、Dir.globを使用した例でディレクトリ探索のコードを見ていこうと思います
また、以下のコードは前回の記事でよりすっきりとしたコードの提案をいただいたのでそちらを使用しております
def traverse(path)
if File.directory?(path)
Dir.each_child(path) do |entry|
path2 = File.join(path, entry)
traverse(path2)
end
else
process_file(path)
end
end
traverse(ARGV[0])
特徴は以下の通りです
-
サブディレクトリを再帰的に探索
再帰呼び出しにより、サブディレクトリ内のファイルも処理します。 -
. や .. を自動的にスキップ
Dir.each_child
は、カレントディレクトリ(.
)や親ディレクトリ(..
)をスキップするため、それらの条件を手動で記述する必要がありません。 -
隠しファイルも探索対象
隠しファイル(例:.gitignore
や.env
)も通常のエントリとして処理されます。
Dir.glob を使ったディレクトリ探索
次に、Dir.glob を使用したコードを見てみましょう。
def traverse(path)
Dir.glob(["#{path}/**/*", "#{path}/**/.*"]) do |name|
unless File.directory?(name)
process_file(name)
end
end
end
def process_file(path)
puts path
end
traverse(ARGV[0])
コードの特徴は以下の通りです
- 再帰処理を明示的に記述する必要がありません。
-
**/*
で通常のファイル、**/.*
で隠しファイルを一括取得。 - 結果をブロックで処理することで、メモリ効率を向上。
Dir.glob を学んだポイント
私は、このコードを通じて Dir.glob の便利さを実感しました。
-
シンプルな記述で再帰探索が可能
再帰呼び出しを自分で記述する必要がなく、Dir.glob
だけでサブディレクトリも含めた探索が実現できます。 -
隠しファイルへの対応が容易
再帰処理コードでは、"."
や".."
をスキップする明示的な記述が必要でしたが、Dir.glob
では**/.*
を追加するだけで簡単に対応できます。 -
メモリ効率の向上
配列で結果を取得する方法ではなく、ブロックを使用して順次処理することで、大量のファイルを扱う際のメモリ消費を抑えることができます。
まとめ
今回の記事では、再帰呼び出しコードと Dir.glob
を使ったコードを比較しながら、その違いや使い方について解説しました。
再帰呼び出しコードは、ディレクトリ探索のロジックを深く理解する良い練習になります。
一方、Dir.glob
を使うと、柔軟で簡潔なコードを実現できます。
それぞれの特徴を抑えて、適切な場面でコードを使い分けれるようにこれからも多用の視点を持って勉強に臨みたいと思います