Dir
The Dir module provides methods for manipulating directories in Ruby. You can read directory contents, change the current working directory, create and remove directories, and more.
Overview
Dir is part of Ruby’s standard library for working with the file system:
- Read: List files and subdirectories
- Navigate: Change the current working directory
- Create: Make new directories
- Delete: Remove empty directories
- Query: Check if paths exist or are directories
Reading Directory Contents
Dir.entries
Returns an array of all entries in a directory, including . and ..:
Dir.entries('/path/to/dir')
# => [".", "..", "file1.txt", "file2.rb", "subdir"]
Dir.children
Returns entries excluding . and ..:
Dir.children('/path/to/dir')
# => ["file1.txt", "file2.rb", "subdir"]
You can specify encoding:
Dir.children('/path/to/dir', encoding: 'UTF-8')
Dir.glob
Find files matching a pattern:
# All Ruby files
Dir.glob('*.rb')
# => ["main.rb", "helper.rb", "app.rb"]
# Recursive search
Dir.glob('**/*.rb')
# => ["lib/a.rb", "lib/b.rb", "spec/c.rb"]
# Multiple patterns
Dir.glob(['*.rb', '*.md'])
Dir.[ ] (Shortcut)
Shortcut for Dir.glob:
Dir['*.rb']
Dir['**/*.txt']
Changing Directories
Dir.chdir
Change the current working directory:
Dir.pwd # => "/home/user"
Dir.chdir('/tmp')
Dir.pwd # => "/tmp"
With a block, temporarily changes directory:
Dir.chdir('/tmp') do
# We're now in /tmp
Dir.pwd
end
# Back to original directory
Without arguments, chdir uses the HOME environment variable:
Dir.chdir # Changes to HOME directory
Dir.pwd / Dir.getwd
Get the current working directory:
Dir.pwd # => "/home/user/project"
Dir.getwd # => "/home/user/project"
Creating and Deleting Directories
Dir.mkdir
Create a directory:
Dir.mkdir('new_folder')
Dir.mkdir('path/to/deep/folder')
With permissions:
Dir.mkdir('restricted', 0755)
Dir.rmdir / Dir.unlink / Dir.delete
Remove an empty directory:
Dir.rmdir('empty_folder')
Dir.unlink('empty_folder') # Alias
Dir.delete('empty_folder') # Alias
These methods raise an error if the directory is not empty.
Querying Directories
Dir.exist? / Dir.exists?
Check if a path is a directory:
Dir.exist?('/path/to/dir') # => true or false
Dir.exists?('/path/to/dir') # Alias (deprecated)
Dir.empty?
Check if a directory is empty:
Dir.mkdir('temp_dir')
Dir.empty?('temp_dir') # => true
Dir.rmdir('temp_dir')
Dir.home
Get the home directory:
Dir.home # => "/home/user"
Dir.home('other') # => "/home/other"
Working with Dir Objects
Dir.new
Open a directory for iteration:
dir = Dir.new('/path/to/dir')
dir.path # => "/path/to/dir"
dir.each { |entry| puts entry }
dir.close
Dir.open (Preferred)
Using Dir.open with a block automatically closes the directory:
Dir.open('/path/to/dir') do |dir|
dir.each { |entry| puts entry }
end
# Automatically closed
Dir#read
Read the next entry from an open directory:
dir = Dir.new('/path/to/dir')
dir.read # => "first_file.txt"
dir.read # => "second_file.rb"
dir.close
Dir#seek
Seek to a specific position:
Dir.open('/path/to/dir') do |dir|
dir.read # First entry
dir.seek(0) # Go back to start
dir.read # First entry again
end
Dir#rewind
Rewind to the beginning:
Dir.open('/path/to/dir') do |dir|
dir.each { |e| }
dir.rewind
dir.each { |e| }
end
Iterating Over Directories
Dir.foreach
Iterate over all entries:
Dir.foreach('/path/to/dir') { |entry| puts entry }
Dir.each
Iterate using a Dir object:
dir = Dir.new('/path/to/dir')
dir.each { |entry| puts entry }
dir.close
Dir.each_child
Iterate excluding . and ..:
Dir.each_child('/path/to/dir') { |entry| puts entry }
Practical Examples
Find All Ruby Files in a Project
ruby_files = Dir.glob('**/*.rb')
ruby_files.each { |f| puts f }
List Files by Extension
files = Dir.children('.').group_by { |f| File.extname(f) }
files.each { |ext, names| puts "#{ext}: #{names.join(', ')}" }
Safe Directory Navigation
original = Dir.pwd
begin
Dir.chdir('/tmp')
# Do work in /tmp
ensure
Dir.chdir(original) # Always restore
end
Or use the block form:
Dir.chdir('/tmp') do
# Work in /tmp
end
# Automatically back to original