NAME
Sidef::Types::Glob::Dir - Directory manipulation and navigation in Sidef
DESCRIPTION
The Dir class provides directory manipulation capabilities in Sidef: creation, deletion, navigation, and traversal of directory structures. It's a subclass of Sidef::Types::Glob::File, so every method documented in Sidef::Types::Glob::File is also available on a Dir object -- though a few of them (read, write, size, and so on) don't really make sense for a directory even though they're technically callable.
Paths are decoded/encoded as UTF-8 where the underlying Perl core modules require it.
SYNOPSIS
# Create a Dir object
var dir = Dir("/path/to/directory")
var home = Dir.home
var temp = Dir.tmp
# Directory creation
dir.create # Create a single directory
dir.create_tree # Create a directory with any needed parents
# Directory navigation
Dir.cwd # Get the current working directory
dir.chdir # Change to this directory
dir.parent # Get the logical parent directory
dir.up # Append ".." (unresolved)
# Directory operations
dir.is_empty # Check if the directory is empty
dir.remove # Remove an empty directory
dir.remove_tree # Recursively remove a directory and its contents
# Directory traversal
dir.find {|item|
say(item) # Iterate over the directory and everything below it
}
# Path manipulation -- '+' only returns a File if given an actual File object!
var subdir = (dir + "subdir") # a Dir, even though it looks like a name
var file = (dir + File("file.txt")) # a File, because the argument already is one
var parts = dir.split # Split the path into components
INHERITS
Inherits methods from Sidef::Types::Glob::File.
CONSTRUCTION
new
Dir(path)
Dir(*path_components)
Dir.new(path)
Creates a new Dir object. With a single string argument, path is used as-is. With more than one argument, the arguments are joined as path components (via File::Spec::catdir) into a single path. With a single argument that's any kind of reference (a File, another Dir, or anything else), this instead delegates entirely to calling .to_dir on it and returns that result -- so the given object's own class must actually provide a working to_dir method.
var dir1 = Dir("/home/user")
var dir2 = Dir("home", "user", "documents")
var dir3 = Dir(some_file_obj) # delegates to some_file_obj.to_dir
Aliases: call
SPECIAL DIRECTORIES
root
Dir.root
Returns a Dir representing the filesystem's root directory ("/" on Unix-like systems).
say(Dir.root) #=> Dir("/")
home
Dir.home
Returns a Dir representing the current user's home directory, determined (in order) from the HOME or LOGDIR environment variables, a system user-database lookup (on non-Windows systems), or File::HomeDir as a last resort.
say(Dir.home) # e.g. Dir("/home/username")
tmp
Dir.tmp
Returns a Dir representing the system's temporary directory.
say(Dir.tmp) # e.g. Dir("/tmp")
Aliases: temp
cwd
Dir.cwd
Returns a Dir representing the current working directory, as an absolute, resolved path.
say(Dir.cwd)
pwd
Dir.pwd
Returns a Dir representing the current directory as the literal, unresolved string "." -- unlike "cwd", this is not turned into an absolute path.
say(Dir.pwd) #=> Dir(".")
mktemp
Dir.mktemp(%options)
Creates a new, empty temporary directory (via File::Temp::tempdir) and returns a Dir for it. It's automatically removed when the program exits (CLEANUP is always enabled). %options are forwarded to File::Temp::tempdir.
var tmpdir = Dir.mktemp
tmpdir.chdir
Aliases: make_tmp, make_temp
PATH MANIPULATION
concat
self.concat(other)
self + other
If other is specifically a File object (not a Dir, and not a plain string, even one that looks like a filename), joins the paths with File::Spec::catfile and returns a File. For anything else -- including a plain string like "file.txt", or a Dir -- joins the paths with File::Spec::catdir instead and returns a Dir. In other words, the only way to get a File back from + is to pass an actual File object; a bare string argument always produces a Dir, regardless of what it looks like.
var home = Dir.home
say(home + "Documents") #=> Dir(".../Documents")
say(home + "file.txt") #=> Dir(".../file.txt") -- still a Dir!
say(home + File("file.txt")) #=> File(".../file.txt") -- a File, because the argument was one
Aliases: operator +, catfile
split
self.split
Splits the directory path into its components, via File::Spec::splitdir, and returns them as an Array of Strings.
say(Dir("/home/user/documents").split) #=> ["", "home", "user", "documents"]
parent
self.parent
Returns a Dir for the logical parent directory, computed textually (via File::Basename::dirname) rather than by consulting the filesystem. Compare with "up", which doesn't compute anything -- it just appends a literal "..".
say(Dir("/home/user/documents").parent) #=> Dir("/home/user")
up
self.up
Dir.up
Returns a new Dir with a literal ".." appended to the path (via File::Spec, so the platform's own separator is used) -- unlike "parent", nothing is resolved or simplified. Called on the Dir class itself (with no instance), returns just Dir("..") on its own, unanchored to any particular directory.
say(Dir("/home/user/documents").up) #=> Dir("/home/user/documents/..")
say(Dir.up) #=> Dir("..")
get_value
self.get_value
Returns the raw underlying path string (unwrapped from the Dir object). A low-level method, mainly useful for interop rather than everyday Sidef code.
to_dir
self.to_dir
Returns self unchanged (a Dir is already a directory).
to_str
self.to_str
Returns the directory's path as a plain String.
say(Dir("/home/user").to_str) #=> "/home/user"
Aliases: to_s
dump
self.dump
Returns a String representation of the Dir object for debugging, in the format Dir("path").
say(Dir("/tmp").dump) #=> Dir("/tmp")
NAVIGATION
chdir
self.chdir
Changes the process's current working directory to this one. Returns true on success, false otherwise. This is process-wide, not local to any particular scope.
Dir("/tmp").chdir
chroot
self.chroot
Changes the process's root directory to this one (typically requires superuser privileges). Returns true on success, false otherwise. Like "chdir", this affects the entire process.
Dir("/jail").chroot
CREATING AND REMOVING
create
self.create
Creates the directory. Its immediate parent must already exist -- for creating any missing parent directories too, see "create_tree". Returns true on success, false otherwise.
Dir("newdir").create
Aliases: make, mkdir
create_tree
self.create_tree
Creates the directory, along with any missing parent directories (like mkdir -p). Returns true if the directory already existed or was successfully created, false otherwise.
Dir("/path/to/deep/nested/dir").create_tree
Aliases: make_tree, mktree, make_path, mkpath
remove
self.remove
Removes the directory. It must be empty -- for removing a directory and everything inside it, see "remove_tree". Returns true on success, false otherwise.
Dir("empty_dir").remove
Aliases: delete, unlink
remove_tree
self.remove_tree
Recursively removes the directory and everything inside it. This cannot be undone. Returns true on success, false otherwise.
Dir("old_project").remove_tree
CONTENTS AND TRAVERSAL
is_empty
self.is_empty
Returns true if the directory contains no entries (other than . and ..), false if it has any, or nil if the directory can't be opened at all.
Dir("test").is_empty && say("Directory is empty")
find
self.find
self.find(block)
Recursively traverses the directory tree, starting from (and including) the directory itself. With a block, calls it once for every item found (a Dir for each subdirectory, a File for each regular file) and returns self. With no block, collects everything into an Array instead.
dir.find {|item|
say(item) if item.is_file
}
var all_items = dir.find
say("Found #{all_items.len} items")
Aliases: browse
open
self.open
self.open(fh_ref, err_ref=nil)
Opens the directory for reading its entries. With no arguments, returns a DirHandle on success, or nil on failure. With fh_ref, stores the handle through it and returns true/false instead (storing any error message through err_ref, if given).
var dh = Dir("/tmp").open
dh.each {|entry| say(entry) }
Aliases: open_r
open_w
self.open_w
Not implemented. Calling this currently raises a runtime "Unimplemented" error -- it's a placeholder for future write-mode directory support, not a harmless no-op.
open_rw
self.open_rw
Not implemented. Like "open_w", calling this currently raises a runtime "Unimplemented" error.
EXAMPLES
Basic directory operations
var project = Dir("my_project")
project.create_tree
project.chdir
var src = (project + "src") # a Dir, since a plain string always produces one
var lib = (project + "lib")
src.create
lib.create
Directory traversal
var docs = Dir("documents")
# find() includes the starting directory itself in the traversal
docs.find {|item|
if (item.is_file && item.match(/\.txt$/)) {
say(item)
}
}
var all = docs.find
say("Total items: #{all.len}")
Temporary directories
var tmpdir = Dir.mktemp
say("Using temp directory: #{tmpdir}")
tmpdir.chdir
# ... work happens here ...
# tmpdir is automatically removed when the program exits
Cleaning up
var old = Dir("obsolete")
old.is_empty && old.remove
var cache = Dir(".cache")
cache.remove_tree # removes everything, recursively
Getting a File, not a Dir, from concatenation
var home = Dir.home
var maybe_dir = (home + "notes.txt") # still a Dir -- plain strings never become Files
var actually_file = (home + File("notes.txt")) # a File, since the argument was one