Question
How can I retrieve the absolute path of the current working directory in Ruby, including from an irb session on Windows?
I know a script can resolve a file path with code such as:
File.expand_path(__FILE__)
However, in irb I attempted the following and received a Permission denied error:
CopyFile.new(Dir.new(".").path).expand
What is the correct Ruby approach?
Short Answer
You will learn the difference between Ruby’s current working directory and the location of a Ruby source file. You will also learn the simplest, portable way to get the current directory’s absolute path: Dir.pwd (or its alias, Dir.getwd).
Concept
The current working directory (often shortened to CWD) is the directory Ruby treats as the starting point for relative paths.
For example, if the working directory is:
C:/Users/Ada/projects/inventory
then this relative path:
"data/items.json"
is interpreted relative to that directory.
Use Dir.pwd to get the current working directory as an absolute path:
Dir.pwd
pwd means print working directory, following the same convention as the shell command.
This works in Ruby scripts and in irb, and it is portable across Windows, macOS, and Linux. Ruby returns paths in the format appropriate for the current operating system.
File.expand_path(__FILE__) answers a different question: it resolves the path of the Ruby file currently being executed. It does not necessarily return the working directory. In irb, there is no ordinary source file corresponding to the typed expression, so __FILE__ is not the right tool for finding the directory where the session started.
Mental Model
Think of the current working directory as Ruby’s current room.
Dir.pwdasks: “Which room am I currently standing in?”- A relative path such as
"notes.txt"means: “Findnotes.txtin this room.” File.expand_path(__FILE__)asks: “Where is the document I am currently reading from?”
A program can be started from one directory while its source file lives in another. Those are separate locations, so choose the method based on which location you need.
Syntax and Examples
The primary syntax is:
Dir.pwd
Example in irb:
irb(main):001> Dir.pwd
=> "C:/Users/Ada/projects/inventory"
Dir.getwd is an alias for the same operation:
Dir.getwd
# => "C:/Users/Ada/projects/inventory"
You can also expand the special relative path ".", which means “the current directory”:
File.expand_path(".")
# => "C:/Users/Ada/projects/inventory"
For this specific task, prefer Dir.pwd because it directly expresses your intent.
To create an absolute path for a file inside the current directory, use File.expand_path with the file name:
config_path = File.expand_path("config/settings.yml")
puts config_path
# C:/Users/Ada/projects/inventory/config/settings.yml
Step by Step Execution
Consider this Ruby code:
puts Dir.pwd
puts File.expand_path("reports/today.txt")
Suppose Ruby was started in:
C:/Users/Ada/projects/inventory
Execution proceeds as follows:
Dir.pwdasks the operating system for Ruby’s current working directory.- Ruby receives
C:/Users/Ada/projects/inventoryand prints it. File.expand_path("reports/today.txt")receives a relative path.- Ruby combines it with the current working directory.
- Ruby normalizes the result and prints:
C:/Users/Ada/projects/inventory/reports/today.txt
File.expand_path calculates a path string. It does not require reports/today.txt to already exist.
Real World Use Cases
Common uses for the current working directory include:
- Command-line scripts: Read files that the user placed in the directory where they ran the command.
- Data imports: Resolve a relative input path such as
"customers.csv"to an absolute path for logging or diagnostics. - Build and automation scripts: Locate project-relative files when a task is intentionally run from the project root.
- Test tools: Display the complete path of generated reports and temporary output.
- Developer tools: Show users where a command is operating before it creates, modifies, or deletes files.
Example: report where an export is written.
output = File.expand_path("output/report.csv")
puts "Writing report to: #{output}"
Real Codebase Usage
In real projects, developers distinguish carefully between paths relative to the working directory and paths relative to the source file.
Working-directory-relative paths
Use these when a command is designed to run from a directory chosen by the user:
input_path = File.expand_path(ARGV.fetch(0, "input.json"))
unless File.file?(input_path)
warn "Input file not found: #{input_path}"
exit 1
end
This validates the resolved absolute path before processing it.
Source-file-relative paths
Use these when a library or script must find files shipped alongside its own code, regardless of where the command was run:
SCRIPT_DIR = __dir__
template_path = File.join(SCRIPT_DIR, "templates", "email.txt")
__dir__ is usually clearer than File.dirname(__FILE__) for this purpose.
Temporarily changing directories
Ruby can run a block in another directory and automatically return afterward:
Dir.chdir("C:/Users/Ada/projects/inventory") do
puts Dir.pwd
# Work with relative paths here.
end
Using the block form avoids accidentally leaving the process in the wrong directory.
Common Mistakes
Using __FILE__ to find the working directory
File.expand_path(__FILE__)
This resolves the current Ruby file’s path, not the directory where the process was launched. In an interactive session, use Dir.pwd instead.
Assuming Dir.new(".") is needed
Dir.new(".").path
This can return ".", which is still a relative path. It creates a directory object, but it is unnecessary when all you need is the working directory.
Use:
Dir.pwd
Using unrelated file-copy APIs
CopyFile.new(Dir.new(".").path).expand
CopyFile is not the standard Ruby API for resolving a directory path. Constructing an object that expects a file or requires access can trigger errors such as Permission denied. Path resolution does not require opening, copying, or reading a directory.
Confusing an absolute path with an existing path
File.expand_path("missing/file.txt")
This returns an absolute string even if the file does not exist. Check separately when existence matters:
path = File.expand_path("missing/file.txt")
puts File.exist?(path)
# false
Depending on the working directory unintentionally
A script may work in one terminal directory and fail in another. If a resource belongs to the application itself, anchor it to the source file with __dir__, not Dir.pwd.
Comparisons
| Expression | What it returns | Best use |
|---|---|---|
Dir.pwd | The process’s current working directory as an absolute path | Find where Ruby is currently operating |
Dir.getwd | Same result as Dir.pwd | Equivalent alias; Dir.pwd is commonly used |
File.expand_path(".") | The current directory as an absolute path | Expand a relative path; works but is less direct for the CWD |
File.expand_path(__FILE__) | Absolute path of the current source file | Locate the running Ruby file |
__dir__ | Directory containing the current source file | Load templates, configuration, or assets next to code |
Dir.new(".").path | Usually the relative string "." | Create a directory object; not needed to get the CWD |
A useful rule is:
- Need the directory Ruby was started in? Use
Dir.pwd. - Need the directory containing this
.rbfile? Use__dir__. - Need to convert a path string to an absolute path? Use
File.expand_path.
Cheat Sheet
# Current working directory (absolute path)
Dir.pwd
# Alias for Dir.pwd
Dir.getwd
# Expand the current directory explicitly
File.expand_path(".")
# Expand a relative file path from the current directory
File.expand_path("logs/app.log")
# Directory containing the current Ruby source file
__dir__
# Absolute path of the current Ruby source file
File.expand_path(__FILE__)
# Change the working directory for a block
Dir.chdir("path/to/directory") do
puts Dir.pwd
end
Key rules:
Dir.pwdworks in both scripts andirb.- Relative paths depend on the current working directory.
File.expand_pathresolves a path but does not verify that it exists.- Use
__dir__when files must be located relative to the source code rather than the launch location.
FAQ
How do I get the current directory in Ruby?
Call Dir.pwd. It returns the current working directory as an absolute path.
Dir.pwd
Does Dir.pwd work in irb on Windows?
Yes. It works in irb, scripts, Windows, macOS, and Linux.
What is the difference between Dir.pwd and File.expand_path(".")?
Both produce the current directory’s absolute path. Dir.pwd is more direct because it explicitly asks for the working directory. File.expand_path is more useful when expanding arbitrary relative paths.
Is Dir.getwd different from Dir.pwd?
No. Dir.getwd is an alias for Dir.pwd.
Why is File.expand_path(__FILE__) not the same as Dir.pwd?
__FILE__ identifies the source file Ruby is evaluating, while Dir.pwd identifies the directory from which the Ruby process is currently operating. They can be different.
Does File.expand_path check whether a file exists?
No. It only resolves and normalizes the path string. Use File.exist?, File.file?, or File.directory? to check the filesystem.
How can I find the directory containing my Ruby script?
Use __dir__ inside the script:
puts __dir__
This is often the correct choice for files packaged with the script.
Mini Project
Description
Build a small command-line path inspector. It prints Ruby’s current working directory and converts a path supplied by the user into an absolute path. This is useful in scripts that accept file names from command-line arguments.
Goal
Create a Ruby script that shows the current working directory and reports whether an optional path exists.
Requirements
Use Dir.pwd to display the current working directory.
Accept an optional path from the first command-line argument.
Use File.expand_path to convert the supplied path to an absolute path.
Report whether the resolved path is a file, a directory, or does not exist.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.