Class: Dir
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
self,
::Enumerable
|
|
Inherits: | Object |
Defined in: | dir.rb, dir.c |
Overview
An object of class Dir represents a directory in the underlying file system.
It consists mainly of:
-
A string path, given when the object is created, that specifies a directory in the underlying file system; method #path returns the path.
-
A collection of string entry names, each of which is the name of a directory or file in the underlying file system; the entry names may be retrieved in an
array-like fashion
or in astream-like fashion
.
About the Examples
Some examples on this page use this simple file tree:
example/
├── config.h
├── lib/
│ ├── song/
│ │ └── karaoke.rb
│ └── song.rb
└── main.rb
Others use the file tree for the Ruby project itself.
Dir As Array-Like
A Dir object is in some ways array-like:
-
It has instance methods #children, #each, and #each_child.
-
It includes
module Enumerable
.
Dir As Stream-Like
A Dir object is in some ways stream-like.
The stream is initially open for reading, but may be closed manually (using method #close), and will be closed on block exit if created by .open called with a block. The closed stream may not be further manipulated, and may not be reopened.
The stream has a position, which is the index of an entry in the directory:
-
The initial position is zero (before the first entry).
-
Method #pos= sets the position (but ignores a value outside the stream), and returns the position.
-
Method #seek is like #pos=, but returns
self
(convenient for chaining). -
Method #read, if not at end-of-stream, reads the next entry and increments the position; if at end-of-stream, does not increment the position.
-
Method #rewind sets the position to zero.
Examples (using the simple file tree
):
dir = Dir.new('example') # => #<Dir:example>
dir.pos # => 0
dir.read # => "."
dir.read # => ".."
dir.read # => "config.h"
dir.read # => "lib"
dir.read # => "main.rb"
dir.pos # => 5
dir.read # => nil
dir.pos # => 5
dir.rewind # => #<Dir:example>
dir.pos # => 0
dir.pos = 3 # => 3
dir.pos # => 3
dir.seek(4) # => #<Dir:example>
dir.pos # => 4
dir.close # => nil
dir.read # Raises IOError.
What’s Here
First, what’s elsewhere. Class Dir:
-
Inherits from
class Object
. -
Includes
module Enumerable
, which provides dozens of additional methods.
Here, class Dir provides methods that are useful for:
-
Reading
-
Setting
-
Querying
-
Iterating
-
Other
Reading
-
#close: Closes the directory stream for
self
. -
#pos=: Sets the position in the directory stream for
self
. -
#read: Reads and returns the next entry in the directory stream for
self
. -
#rewind: Sets the position in the directory stream for
self
to the first entry. -
#seek: Sets the position in the directory stream for
self
the entry at the given offset.
Setting
-
.chdir: Changes the working directory of the current process to the given directory.
-
.chroot: Changes the file-system root for the current process to the given directory.
Querying
-
.children: Returns an array of names of the children (both files and directories) of the given directory, but not including
.
or..
. -
.empty?: Returns whether the given path is an empty directory.
-
.entries: Returns an array of names of the children (both files and directories) of the given directory, including
.
and..
. -
.exist?: Returns whether the given path is a directory.
-
.getwd (aliased as
#pwd
): Returns the path to the current working directory. -
.glob: Returns an array of file paths matching the given pattern and flags.
-
.home: Returns the home directory path for a given user or the current user.
-
#children: Returns an array of names of the children (both files and directories) of
self
, but not including.
or..
. -
#fileno: Returns the integer file descriptor for
self
. -
#path (aliased as #to_path): Returns the path used to create
self
. -
#tell (aliased as #pos): Returns the integer position in the directory stream for
self
.
Iterating
-
.each_child: Calls the given block with each entry in the given directory, but not including
.
or..
. -
.foreach: Calls the given block with each entry in the given directory, including
.
and..
. -
#each: Calls the given block with each entry in
self
, including.
and..
. -
#each_child: Calls the given block with each entry in
self
, but not including.
or..
.
Other
-
.mkdir: Creates a directory at the given path, with optional permissions.
-
.new: Returns a new Dir for the given path, with optional encoding.
-
.open: Same as .new, but if a block is given, yields the Dir to the block, closing it upon block exit.
-
.unlink (aliased as .delete and .rmdir): Removes the given directory.
-
#inspect: Returns a string description of
self
.
Class Method Summary
-
.[](*patterns, base: nil, sort: true) ⇒ Array
Calls .glob with argument
patterns
and the values of keyword argumentsbase
andsort
; returns the array of selected entry names. -
.chdir(new_dirpath) ⇒ 0
Changes the current working directory.
-
.children(dirpath) ⇒ Array
Returns an array of the entry names in the directory at
dirpath
except for'.'
and'..'
; sets the given encoding onto each returned entry name: -
.chroot(dirpath) ⇒ 0
Changes the root directory of the calling process to that specified in
dirpath
. -
.delete(dirpath) ⇒ 0
Alias for .rmdir.
-
.each_child(dirpath) {|entry_name| ... } ⇒ nil
Like .foreach, except that entries
'.'
and'..'
are not included. -
.empty?(dirpath) ⇒ Boolean
Returns whether
dirpath
specifies an empty directory: -
.entries(dirname, encoding: 'UTF-8') ⇒ Array
Returns an array of the entry names in the directory at
dirpath
; sets the given encoding onto each returned entry name: -
.exist?(dirpath) ⇒ Boolean
Returns whether
dirpath
is a directory in the underlying file system: -
.fchdir(fd) ⇒ 0
Changes the current working directory to the directory specified by the integer file descriptor
fd
. -
.for_fd(fd) ⇒ Dir
Returns a new Dir object representing the directory specified by the given integer directory file descriptor
fd
: -
.foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } ⇒ nil
Calls the block with each entry name in the directory at
dirpath
; sets the given encoding onto each passedentry_name
: -
.getwd ⇒ String
Alias for .pwd.
-
.glob(*patterns, flags: 0, base: nil, sort: true) ⇒ Array
Forms an array entry_names of the entry names selected by the arguments.
-
.home(user_name = nil) ⇒ Dir
Retruns the home directory path of the user specified with
user_name
if it is notnil
, or the current login user: -
.mkdir(dirpath, permissions = 0775) ⇒ 0
Creates a directory in the underlying file system at
dirpath
with the givenpermissions
; returns zero: -
.new(dirpath) ⇒ Dir
constructor
Returns a new Dir object for the directory at
dirpath
: -
.open(dirpath) ⇒ Dir
Creates a new Dir object dir for the directory at
dirpath
. -
.pwd ⇒ String
(also: .getwd)
Returns the path to the current working directory:
-
.rmdir(dirpath) ⇒ 0
(also: .delete, .unlink)
Removes the directory at
dirpath
from the underlying file system: -
.unlink(dirpath) ⇒ 0
Alias for .rmdir.
Instance Attribute Summary
-
#pos ⇒ Integer
(also: #tell)
rw
Returns the current position of
self
; see
:Dir
As Stream-Like -
#pos=(position) ⇒ Integer
rw
Sets the position in
self
and returnsposition
. -
#tell ⇒ Integer
readonly
Alias for #pos.
Instance Method Summary
-
#chdir ⇒ 0
Changes the current working directory to
self
: -
#children ⇒ Array
Returns an array of the entry names in
self
except for'.'
and'..'
: -
#close ⇒ nil
Closes the stream in
self
, if it is open, and returnsnil
; ignored ifself
is already closed: -
#each {|entry_name| ... } ⇒ self
Calls the block with each entry name in
self
: -
#each_child {|entry_name| ... } ⇒ self
Calls the block with each entry name in
self
except'.'
and'..'
: -
#fileno ⇒ Integer
Returns the file descriptor used in dir.
-
#inspect ⇒ String
Returns a string description of
self
: -
#path ⇒ String?
(also: #to_path)
Returns the
dirpath
string that was used to createself
(ornil
if created by method .for_fd): -
#read ⇒ String?
Reads and returns the next entry name from
self
; returnsnil
if at end-of-stream; see
:Dir
As Stream-Like -
#rewind ⇒ self
Sets the position in
self
to zero; see
:Dir
As Stream-Like -
#seek(position) ⇒ self
Sets the position in
self
and returnsself
. -
#to_path ⇒ String?
Alias for #path.
::Enumerable
- Included
#all? | Returns whether every element meets a given criterion. |
#any? | Returns whether any element meets a given criterion. |
#chain | Returns an enumerator object generated from this enumerator and given enumerables. |
#chunk | Each element in the returned enumerator is a 2-element array consisting of: |
#chunk_while | Creates an enumerator for each chunked elements. |
#collect | Alias for Enumerable#map. |
#collect_concat | Alias for Enumerable#flat_map. |
#compact | Returns an array of all non- |
#count | Returns the count of elements, based on an argument or block criterion, if given. |
#cycle | When called with positive integer argument |
#detect | Alias for Enumerable#find. |
#drop | For positive integer |
#drop_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements after that point: |
#each_cons | Calls the block with each successive overlapped |
#each_entry | Calls the given block with each element, converting multiple values from yield to an array; returns |
#each_slice | Calls the block with each successive disjoint |
#each_with_index | With a block given, calls the block with each element and its index; returns |
#each_with_object | Calls the block once for each element, passing both the element and the given object: |
#entries | Alias for Enumerable#to_a. |
#filter | Returns an array containing elements selected by the block. |
#filter_map | Returns an array containing truthy elements returned by the block. |
#find | Returns the first element for which the block returns a truthy value. |
#find_all | Alias for Enumerable#filter. |
#find_index | Returns the index of the first element that meets a specified criterion, or |
#first | Returns the first element or elements. |
#flat_map | Returns an array of flattened objects returned by the block. |
#grep | Returns an array of objects based elements of |
#grep_v | Returns an array of objects based on elements of |
#group_by | With a block given returns a hash: |
#include? | Alias for Enumerable#member?. |
#inject | Returns an object formed from operands via either: |
#lazy | Returns an |
#map | Returns an array of objects returned by the block. |
#max | Returns the element with the maximum element according to a given criterion. |
#max_by | Returns the elements for which the block returns the maximum values. |
#member? | Returns whether for any element |
#min | Returns the element with the minimum element according to a given criterion. |
#min_by | Returns the elements for which the block returns the minimum values. |
#minmax | Returns a 2-element array containing the minimum and maximum elements according to a given criterion. |
#minmax_by | Returns a 2-element array containing the elements for which the block returns minimum and maximum values: |
#none? | Returns whether no element meets a given criterion. |
#one? | Returns whether exactly one element meets a given criterion. |
#partition | With a block given, returns an array of two arrays: |
#reduce | Alias for Enumerable#inject. |
#reject | Returns an array of objects rejected by the block. |
#reverse_each | With a block given, calls the block with each element, but in reverse order; returns |
#select | Alias for Enumerable#filter. |
#slice_after | Creates an enumerator for each chunked elements. |
#slice_before | With argument |
#slice_when | Creates an enumerator for each chunked elements. |
#sort | Returns an array containing the sorted elements of |
#sort_by | With a block given, returns an array of elements of |
#sum | With no block given, returns the sum of |
#take | For non-negative integer |
#take_while | Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements up to that point: |
#tally | Returns a hash containing the counts of equal elements: |
#to_a | Returns an array containing the items in |
#to_h | When |
#to_set | Makes a set from the enumerable object with given arguments. |
#uniq | With no block, returns a new array containing only unique elements; the array has no two elements |
#zip | With no block given, returns a new array |
Constructor Details
.new(dirpath) ⇒ Dir
.new(dirpath, encoding: nil) ⇒ Dir
Dir
.new(dirpath, encoding: nil) ⇒ Dir
Returns a new Dir object for the directory at dirpath
:
Dir.new('.') # => #<Dir:.>
The value given with optional keyword argument encoding
specifies the encoding for the directory entry names; if nil
(the default), the file system’s encoding is used:
Dir.new('.').read.encoding # => #<Encoding:UTF-8>
Dir.new('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII>
# File 'dir.rb', line 211
def initialize(name, encoding: nil) Primitive.dir_initialize(name, encoding) end
Class Method Details
.[](*patterns, base: nil, sort: true) ⇒ Array
Calls .glob with argument patterns
and the values of keyword arguments base
and sort
; returns the array of selected entry names.
# File 'dir.rb', line 222
def self.[](*args, base: nil, sort: true) Primitive.dir_s_aref(args, base, sort) end
Changes the current working directory.
With argument new_dirpath
and no block, changes to the given dirpath
:
Dir.pwd # => "/example"
Dir.chdir('..') # => 0
Dir.pwd # => "/"
With no argument and no block:
-
Changes to the value of environment variable
HOME
if defined. -
Otherwise changes to the value of environment variable
LOGDIR
if defined. -
Otherwise makes no change.
With argument new_dirpath
and a block, temporarily changes the working directory:
-
Calls the block with the argument.
-
Changes to the given directory.
-
Executes the block (yielding the new path).
-
Restores the previous working directory.
-
Returns the block’s return value.
Example:
Dir.chdir('/var/spool/mail')
Dir.pwd # => "/var/spool/mail"
Dir.chdir('/tmp') do
Dir.pwd # => "/tmp"
end
Dir.pwd # => "/var/spool/mail"
With no argument and a block, calls the block with the current working directory (string) and returns the block’s return value.
Calls to Dir.chdir with blocks may be nested:
Dir.chdir('/var/spool/mail')
Dir.pwd # => "/var/spool/mail"
Dir.chdir('/tmp') do
Dir.pwd # => "/tmp"
Dir.chdir('/usr') do
Dir.pwd # => "/usr"
end
Dir.pwd # => "/tmp"
end
Dir.pwd # => "/var/spool/mail"
In a multi-threaded program an error is raised if a thread attempts to open a chdir
block while another thread has one open, or a call to chdir
without a block occurs inside a block passed to chdir
(even in the same thread).
Raises an exception if the target directory does not exist.
# File 'dir.c', line 1171
static VALUE dir_s_chdir(int argc, VALUE *argv, VALUE obj) { VALUE path = Qnil; if (rb_check_arity(argc, 0, 1) == 1) { path = rb_str_encode_ospath(rb_get_path(argv[0])); } else { const char *dist = getenv("HOME"); if (!dist) { dist = getenv("LOGDIR"); if (!dist) rb_raise(rb_eArgError, "HOME/LOGDIR not set"); } path = rb_str_new2(dist); } return chdir_path(path, true); }
Returns an array of the entry names in the directory at dirpath
except for '.'
and '..'
; sets the given encoding onto each returned entry name:
Dir.children('/example') # => ["config.h", "lib", "main.rb"]
Dir.children('/example').first.encoding
# => #<Encoding:UTF-8>
Dir.children('/example', encoding: 'US-ASCII').first.encoding
# => #<Encoding:US-ASCII>
See {String
Encoding}.
Raises an exception if the directory does not exist.
# File 'dir.c', line 3420
static VALUE dir_s_children(int argc, VALUE *argv, VALUE io) { VALUE dir; dir = dir_open_dir(argc, argv); return rb_ensure(dir_collect_children, dir, dir_close, dir); }
.chroot(dirpath) ⇒ 0
Changes the root directory of the calling process to that specified in dirpath
. The new root directory is used for pathnames beginning with '/'
. The root directory is inherited by all children of the calling process.
Only a privileged process may call chroot
.
See Linux chroot.
# File 'dir.c', line 1451
static VALUE dir_s_chroot(VALUE dir, VALUE path) { path = check_dirname(path); if (chroot(RSTRING_PTR(path)) == -1) rb_sys_fail_path(path); return INT2FIX(0); }
.rmdir(dirpath) ⇒ 0
.delete(dirpath) ⇒ 0
0
.delete(dirpath) ⇒ 0
Alias for .rmdir.
.each_child(dirpath) {|entry_name| ... } ⇒ nil
.each_child(dirpath, encoding: 'UTF-8') {|entry_name| ... } ⇒ nil
nil
.each_child(dirpath, encoding: 'UTF-8') {|entry_name| ... } ⇒ nil
Like .foreach, except that entries '.'
and '..'
are not included.
# File 'dir.c', line 3346
static VALUE dir_s_each_child(int argc, VALUE *argv, VALUE io) { VALUE dir; RETURN_ENUMERATOR(io, argc, argv); dir = dir_open_dir(argc, argv); rb_ensure(dir_each_child, dir, dir_close, dir); return Qnil; }
.empty?(dirpath) ⇒ Boolean
Returns whether dirpath
specifies an empty directory:
dirpath = '/tmp/foo'
Dir.mkdir(dirpath)
Dir.empty?(dirpath) # => true
Dir.empty?('/example') # => false
Dir.empty?('/example/main.rb') # => false
Raises an exception if dirpath
does not specify a directory or file in the underlying file system.
# File 'dir.c', line 3589
static VALUE rb_dir_s_empty_p(VALUE obj, VALUE dirname) { VALUE result, orig; const char *path; enum {false_on_notdir = 1}; FilePathValue(dirname); orig = rb_str_dup_frozen(dirname); dirname = rb_str_encode_ospath(dirname); dirname = rb_str_dup_frozen(dirname); path = RSTRING_PTR(dirname); #if defined HAVE_GETATTRLIST && defined ATTR_DIR_ENTRYCOUNT { u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)]; struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,}; if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) != 0) rb_sys_fail_path(orig); if (*(const fsobj_tag_t *)(attrbuf+1) == VT_HFS) { al.commonattr = 0; al.dirattr = ATTR_DIR_ENTRYCOUNT; if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) == 0) { if (attrbuf[0] >= 2 * sizeof(u_int32_t)) return RBOOL(attrbuf[1] == 0); if (false_on_notdir) return Qfalse; } rb_sys_fail_path(orig); } } #endif result = (VALUE)rb_thread_call_without_gvl(nogvl_dir_empty_p, (void *)path, RUBY_UBF_IO, 0); if (FIXNUM_P(result)) { rb_syserr_fail_path((int)FIX2LONG(result), orig); } return result; }
.entries(dirname, encoding: 'UTF-8') ⇒ Array
Returns an array of the entry names in the directory at dirpath
; sets the given encoding onto each returned entry name:
Dir.entries('/example') # => ["config.h", "lib", "main.rb", "..", "."]
Dir.entries('/example').first.encoding
# => #<Encoding:UTF-8>
Dir.entries('/example', encoding: 'US-ASCII').first.encoding
# => #<Encoding:US-ASCII>
See {String
Encoding}.
Raises an exception if the directory does not exist.
# File 'dir.c', line 3323
static VALUE dir_entries(int argc, VALUE *argv, VALUE io) { VALUE dir; dir = dir_open_dir(argc, argv); return rb_ensure(dir_collect, dir, dir_close, dir); }
.exist?(dirpath) ⇒ Boolean
Returns whether dirpath
is a directory in the underlying file system:
Dir.exist?('/example') # => true
Dir.exist?('/nosuch') # => false
Dir.exist?('/example/main.rb') # => false
Same as File.directory?.
# File 'dir.c', line 3537
VALUE rb_file_directory_p(void) { }
.fchdir(fd) ⇒ 0
.fchdir(fd) ⇒ Object
0
.fchdir(fd) ⇒ Object
Changes the current working directory to the directory specified by the integer file descriptor fd
.
When passing a file descriptor over a UNIX socket or to a child process, using fchdir
instead of .chdir avoids the time-of-check to time-of-use vulnerability
With no block, changes to the directory given by fd
:
Dir.chdir('/var/spool/mail')
Dir.pwd # => "/var/spool/mail"
dir = Dir.new('/usr')
fd = dir.fileno
Dir.fchdir(fd)
Dir.pwd # => "/usr"
With a block, temporarily changes the working directory:
-
Calls the block with the argument.
-
Changes to the given directory.
-
Executes the block (yields no args).
-
Restores the previous working directory.
-
Returns the block’s return value.
Example:
Dir.chdir('/var/spool/mail')
Dir.pwd # => "/var/spool/mail"
dir = Dir.new('/tmp')
fd = dir.fileno
Dir.fchdir(fd) do
Dir.pwd # => "/tmp"
end
Dir.pwd # => "/var/spool/mail"
This method uses the fchdir() function defined by POSIX 2008; the method is not implemented on non-POSIX platforms (raises ::NotImplementedError
).
Raises an exception if the file descriptor is not valid.
In a multi-threaded program an error is raised if a thread attempts to open a .chdir block while another thread has one open, or a call to .chdir without a block occurs inside a block passed to .chdir (even in the same thread).
# File 'dir.c', line 1291
static VALUE dir_s_fchdir(VALUE klass, VALUE fd_value) { int fd = RB_NUM2INT(fd_value); if (chdir_blocking > 0) { if (rb_thread_current() != chdir_thread) rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block"); if (!rb_block_given_p()) rb_warn("conflicting chdir during another chdir block"); } if (rb_block_given_p()) { struct fchdir_data args; args.old_dir = dir_s_alloc(klass); dir_initialize(NULL, args.old_dir, rb_fstring_cstr("."), Qnil); args.fd = fd; args.done = FALSE; return rb_ensure(fchdir_yield, (VALUE)&args, fchdir_restore, (VALUE)&args); } else { int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_fchdir, &fd, RUBY_UBF_IO, 0); if (r < 0) rb_sys_fail("fchdir"); } return INT2FIX(0); }
.for_fd(fd) ⇒ Dir
Returns a new Dir object representing the directory specified by the given integer directory file descriptor fd
:
d0 = Dir.new('..')
d1 = Dir.for_fd(d0.fileno)
Note that the returned d1
does not have an associated path:
d0.path # => '..'
d1.path # => nil
This method uses the fdopendir() function defined by POSIX 2008; the method is not implemented on non-POSIX platforms (raises ::NotImplementedError
).
# File 'dir.c', line 610
static VALUE dir_s_for_fd(VALUE klass, VALUE fd) { struct dir_data *dp; VALUE dir = TypedData_Make_Struct(klass, struct dir_data, &dir_data_type, dp); if (!(dp->dir = fdopendir(NUM2INT(fd)))) { rb_sys_fail("fdopendir"); UNREACHABLE_RETURN(Qnil); } RB_OBJ_WRITE(dir, &dp->path, Qnil); return dir; }
.foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } ⇒ nil
Calls the block with each entry name in the directory at dirpath
; sets the given encoding onto each passed entry_name
:
Dir.foreach('/example') {|entry_name| p entry_name }
Output:
"config.h"
"lib"
"main.rb"
".."
"."
Dir.foreach('/example') {|entry_name| p entry_name.encoding; break }
Dir.foreach('/example', encoding: 'US-ASCII') {|entry_name| p entry_name.encoding; break }
Output:
#<Encoding:UTF-8>
#<Encoding:US-ASCII>
See {String
Encoding}.
Returns an enumerator if no block is given.
# File 'dir.c', line 3287
static VALUE dir_foreach(int argc, VALUE *argv, VALUE io) { VALUE dir; RETURN_ENUMERATOR(io, argc, argv); dir = dir_open_dir(argc, argv); rb_ensure(dir_each, dir, dir_close, dir); return Qnil; }
Alias for .pwd.
.glob(*patterns, flags: 0, base: nil, sort: true) ⇒ Array
.glob(*patterns, flags: 0, base: nil, sort: true) {|entry_name| ... } ⇒ nil
nil
Forms an array entry_names of the entry names selected by the arguments.
Argument patterns
is a string pattern or an array of string patterns; note that these are not regexps; see below.
Notes for the following examples:
-
'*'
is the pattern that matches any entry name except those that begin with'.'
. -
We use method Array#take to shorten returned arrays that otherwise would be very large.
With no block, returns array entry_names; example (using the simple file tree
):
Dir.glob('*') # => ["config.h", "lib", "main.rb"]
With a block, calls the block with each of the entry_names and returns nil
:
Dir.glob('*') {|entry_name| puts entry_name } # => nil
Output:
config.h
lib
main.rb
If optional keyword argument flags
is given, the value modifies the matching; see below.
If optional keyword argument base
is given, its value specifies the base directory. Each pattern string specifies entries relative to the base directory; the default is '.'
. The base directory is not prepended to the entry names in the result:
Dir.glob(pattern, base: 'lib').take(5)
# => ["abbrev.gemspec", "abbrev.rb", "base64.gemspec", "base64.rb", "benchmark.gemspec"]
Dir.glob(pattern, base: 'lib/irb').take(5)
# => ["cmd", "color.rb", "color_printer.rb", "completion.rb", "context.rb"]
If optional keyword sort
is given, its value specifies whether the array is to be sorted; the default is true
. Passing value false
with that keyword disables sorting (though the underlying file system may already have sorted the array).
Patterns
Each pattern string is expanded according to certain metacharacters; examples below use the Ruby file tree
:
-
'*'
: Matches any substring in an entry name, similar in meaning to regexp/.*/mx
; may be restricted by other values in the pattern strings:-
'*'
matches all entry names:Dir.glob('*').take(3) # => ["BSDL", "CONTRIBUTING.md", "COPYING"]
-
'c*'
matches entry names beginning with'c'
:Dir.glob('c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
-
'*c'
matches entry names ending with'c'
:Dir.glob('*c').take(3) # => ["addr2line.c", "array.c", "ast.c"]
-
'*c*'
matches entry names that contain'c'
, even at the beginning or end:Dir.glob('*c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"]
Does not match Unix-like hidden entry names (“dot files”). To include those in the matched entry names, use flag IO::FNM_DOTMATCH or something like
'{*,.*}'
. -
-
'**'
: Matches entry names recursively if followed by the slash character'/'
:Dir.glob('**/').take(3) # => ["basictest/", "benchmark/", "benchmark/gc/"]
If the string pattern contains other characters or is not followed by a slash character, it is equivalent to
'*'
. -
'?'
Matches any single character; similar in meaning to regexp/./
:Dir.glob('io.?') # => ["io.c"]
-
'[set]'
: Matches any one character in the string set; behaves like aRegexp character class
, including set negation ('[^a-z]'
):Dir.glob('*.[a-z][a-z]').take(3) # => ["CONTRIBUTING.md", "COPYING.ja", "KNOWNBUGS.rb"]
-
'{abc,xyz}'
: Matches either string abc or string xyz; behaves likeRegexp alternation
:Dir.glob('{LEGAL,BSDL}') # => ["LEGAL", "BSDL"]
More than two alternatives may be given.
-
\
: Escapes the following metacharacter.Note that on Windows, the backslash character may not be used in a string pattern:
Dir['c:\foo*']
will not work, useDir['c:/foo*']
instead.
More examples (using the simple file tree
):
# We're in the example directory.
File.basename(Dir.pwd) # => "example"
Dir.glob('config.?') # => ["config.h"]
Dir.glob('*.[a-z][a-z]') # => ["main.rb"]
Dir.glob('*.[^r]*') # => ["config.h"]
Dir.glob('*.{rb,h}') # => ["main.rb", "config.h"]
Dir.glob('*') # => ["config.h", "lib", "main.rb"]
Dir.glob('*', File::FNM_DOTMATCH) # => [".", "config.h", "lib", "main.rb"]
Dir.glob(["*.rb", "*.h"]) # => ["main.rb", "config.h"]
Dir.glob('**/*.rb')
#=> ["lib/song/karaoke.rb", "lib/song.rb", "main.rb"]
Dir.glob('**/*.rb', base: 'lib') # => ["song/karaoke.rb", "song.rb"]
Dir.glob('**/lib') # => ["lib"]
Dir.glob('**/lib/**/*.rb') # => ["lib/song/karaoke.rb", "lib/song.rb"]
Dir.glob('**/lib/*.rb') # => ["lib/song.rb"]
Flags
If optional keyword argument flags
is given (the default is zero – no flags), its value should be the bitwise OR of one or more of the constants defined in module ::File::Constants
.
Example:
flags = File::FNM_EXTGLOB | File::FNM_DOTMATCH
Specifying flags can extend, restrict, or otherwise modify the matching.
The flags for this method (other constants in ::File::Constants
do not apply):
-
File::FNM_DOTMATCH
: specifies that entry names beginning with'.'
should be considered for matching:Dir.glob('*').take(5) # => ["BSDL", "CONTRIBUTING.md", "COPYING", "COPYING.ja", "GPL"] Dir.glob('*', flags: File::FNM_DOTMATCH).take(5) # => [".", ".appveyor.yml", ".cirrus.yml", ".dir-locals.el", ".document"]
-
File::FNM_EXTGLOB
: enables the pattern extension'{a,b}'
, which matches pattern a and pattern b; behaves like a regexp union (e.g.,'(?:a|b)'
):pattern = '{LEGAL,BSDL}' Dir.glob(pattern) # => ["LEGAL", "BSDL"]
-
File::FNM_NOESCAPE
: specifies that escaping with the backslash character'\'
is disabled; the character is not an escape character. -
File::FNM_PATHNAME
: specifies that metacharacters'*'
and'?'
do not match directory separators. -
File::FNM_SHORTNAME
: specifies that patterns may match short names if they exist; Windows only.
# File 'dir.rb', line 410
def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true) Primitive.dir_s_glob(pattern, flags, base, sort) end
.home(user_name = nil) ⇒ Dir
Retruns the home directory path of the user specified with user_name
if it is not nil
, or the current login user:
Dir.home # => "/home/me"
Dir.home('root') # => "/root"
Raises ArgumentError if user_name
is not a user name.
# File 'dir.c', line 3503
static VALUE dir_s_home(int argc, VALUE *argv, VALUE obj) { VALUE user; const char *u = 0; rb_check_arity(argc, 0, 1); user = (argc > 0) ? argv[0] : Qnil; if (!NIL_P(user)) { SafeStringValue(user); rb_must_asciicompat(user); u = StringValueCStr(user); if (*u) { return rb_home_dir_of(user, rb_str_new(0, 0)); } } return rb_default_home_dir(rb_str_new(0, 0)); }
.mkdir(dirpath, permissions = 0775) ⇒ 0
Creates a directory in the underlying file system at dirpath
with the given permissions
; returns zero:
Dir.mkdir('foo')
File.stat(Dir.new('foo')).mode.to_s(8)[1..4] # => "0755"
Dir.mkdir('bar', 0644)
File.stat(Dir.new('bar')).mode.to_s(8)[1..4] # => "0644"
See {File
Permissions}. Note that argument permissions
is ignored on Windows.
# File 'dir.c', line 1493
static VALUE dir_s_mkdir(int argc, VALUE *argv, VALUE obj) { struct mkdir_arg m; VALUE path, vmode; int r; if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) { m.mode = NUM2MODET(vmode); } else { m.mode = 0777; } path = check_dirname(path); m.path = RSTRING_PTR(path); r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_mkdir, &m, RUBY_UBF_IO, 0); if (r < 0) rb_sys_fail_path(path); return INT2FIX(0); }
Creates a new Dir object dir for the directory at dirpath
.
With no block, the method equivalent to .new(dirpath, encoding):
Dir.open('.') # => #<Dir:.>
With a block given, the block is called with the created dir; on block exit dir is closed and the block’s value is returned:
Dir.open('.') {|dir| dir.inspect } # => "#<Dir:.>"
The value given with optional keyword argument encoding
specifies the encoding for the directory entry names; if nil
(the default), the file system’s encoding is used:
Dir.open('.').read.encoding # => #<Encoding:UTF-8>
Dir.open('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII>
# File 'dir.rb', line 183
def self.open(name, encoding: nil, &block) dir = Primitive.dir_s_open(name, encoding) if block begin yield dir ensure Primitive.dir_s_close(dir) end else dir end end
.pwd ⇒ String Also known as: .getwd
Returns the path to the current working directory:
Dir.chdir("/tmp") # => 0
Dir.pwd # => "/tmp"
# File 'dir.c', line 1412
static VALUE dir_s_getwd(VALUE dir) { return rb_dir_getwd(); }
.rmdir(dirpath) ⇒ 0
Also known as: .delete, .unlink
Removes the directory at dirpath
from the underlying file system:
Dir.rmdir('foo') # => 0
Raises an exception if the directory is not empty.
# File 'dir.c', line 1534
static VALUE dir_s_rmdir(VALUE obj, VALUE dir) { const char *p; int r; dir = check_dirname(dir); p = RSTRING_PTR(dir); r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0); if (r < 0) rb_sys_fail_path(dir); return INT2FIX(0); }
.rmdir(dirpath) ⇒ 0
.unlink(dirpath) ⇒ 0
0
.unlink(dirpath) ⇒ 0
Alias for .rmdir.
Instance Attribute Details
#pos ⇒ Integer (rw) Also known as: #tell
# File 'dir.c', line 897
static VALUE dir_tell(VALUE dir) { struct dir_data *dirp; long pos; GetDIR(dir, dirp); pos = telldir(dirp->dir); return rb_int2inum(pos); }
#pos=(position) ⇒ Integer (rw)
Sets the position in self
and returns position
. The value of position
should have been returned from an earlier call to #tell; if not, the return values from subsequent calls to #read are unspecified.
See
.Dir
As Stream-Like
Examples:
dir = Dir.new('example')
dir.pos # => 0
dir.pos = 3 # => 3
dir.pos # => 3
dir.pos = 30 # => 30
dir.pos # => 5
# File 'dir.c', line 967
static VALUE dir_set_pos(VALUE dir, VALUE pos) { dir_seek(dir, pos); return pos; }
Alias for #pos.
Instance Method Details
#chdir ⇒ 0
#chdir ⇒ Object
0
#chdir ⇒ Object
Changes the current working directory to self
:
Dir.pwd # => "/"
dir = Dir.new('example')
dir.chdir
Dir.pwd # => "/example"
With a block, temporarily changes the working directory:
-
Calls the block.
-
Changes to the given directory.
-
Executes the block (yields no args).
-
Restores the previous working directory.
-
Returns the block’s return value.
Uses .fchdir if available, and .chdir if not, see those methods for caveats.
# File 'dir.c', line 1347
static VALUE dir_chdir(VALUE dir) { #if defined(HAVE_FCHDIR) && defined(HAVE_DIRFD) && HAVE_FCHDIR && HAVE_DIRFD return dir_s_fchdir(rb_cDir, dir_fileno(dir)); #else return chdir_path(dir_get(dir)->path, false); #endif }
#children ⇒ Array
Returns an array of the entry names in self
except for '.'
and '..'
:
dir = Dir.new('/example')
dir.children # => ["config.h", "lib", "main.rb"]
# File 'dir.c', line 3393
static VALUE dir_collect_children(VALUE dir) { VALUE ary = rb_ary_new(); dir_each_entry(dir, rb_ary_push, ary, TRUE); return ary; }
#close ⇒ nil
# File 'dir.c', line 1016
static VALUE dir_close(VALUE dir) { struct dir_data *dirp; dirp = dir_get(dir); if (!dirp->dir) return Qnil; closedir(dirp->dir); dirp->dir = NULL; return Qnil; }
#each {|entry_name| ... } ⇒ self
Calls the block with each entry name in self
:
Dir.new('example').each {|entry_name| p entry_name }
Output:
"."
".."
"config.h"
"lib"
"main.rb"
With no block given, returns an ::Enumerator
.
# File 'dir.c', line 844
static VALUE dir_each(VALUE dir) { RETURN_ENUMERATOR(dir, 0, 0); return dir_each_entry(dir, dir_yield, Qnil, FALSE); }
#each_child {|entry_name| ... } ⇒ self
Calls the block with each entry name in self
except '.'
and '..'
:
dir = Dir.new('/example')
dir.each_child {|entry_name| p entry_name }
Output:
"config.h"
"lib"
"main.rb"
If no block is given, returns an enumerator.
# File 'dir.c', line 3375
static VALUE dir_each_child_m(VALUE dir) { RETURN_ENUMERATOR(dir, 0, 0); return dir_each_entry(dir, dir_yield, Qnil, TRUE); }
#fileno ⇒ Integer
Returns the file descriptor used in dir.
d = Dir.new('..')
d.fileno # => 8
This method uses the dirfd() function defined by POSIX 2008; the method is not implemented on non-POSIX platforms (raises ::NotImplementedError
).
# File 'dir.c', line 708
static VALUE dir_fileno(VALUE dir) { struct dir_data *dirp; int fd; GetDIR(dir, dirp); fd = dirfd(dirp->dir); if (fd == -1) rb_sys_fail("dirfd"); return INT2NUM(fd); }
#inspect ⇒ String
Returns a string description of self
:
Dir.new('example').inspect # => "#<Dir:example>"
# File 'dir.c', line 663
static VALUE dir_inspect(VALUE dir) { struct dir_data *dirp; TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dirp); if (!NIL_P(dirp->path)) { VALUE str = rb_str_new_cstr("#<"); rb_str_append(str, rb_class_name(CLASS_OF(dir))); rb_str_cat2(str, ":"); rb_str_append(str, dirp->path); rb_str_cat2(str, ">"); return str; } return rb_funcallv(dir, idTo_s, 0, 0); }
#path ⇒ String? Also known as: #to_path
# File 'dir.c', line 734
static VALUE dir_path(VALUE dir) { struct dir_data *dirp; TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dirp); if (NIL_P(dirp->path)) return Qnil; return rb_str_dup(dirp->path); }
#read ⇒ String?
Reads and returns the next entry name from self
; returns nil
if at end-of-stream; see
:Dir
As Stream-Like
dir = Dir.new('example')
dir.read # => "."
dir.read # => ".."
dir.read # => "config.h"
# File 'dir.c', line 799
static VALUE dir_read(VALUE dir) { struct dir_data *dirp; struct dirent *dp; GetDIR(dir, dirp); rb_errno_set(0); if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) { return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc); } else { int e = errno; if (e != 0) rb_syserr_fail(e, 0); return Qnil; /* end of stream */ } }
#rewind ⇒ self
# File 'dir.c', line 992
static VALUE dir_rewind(VALUE dir) { struct dir_data *dirp; GetDIR(dir, dirp); rewinddir(dirp->dir); return dir; }
#seek(position) ⇒ self
Sets the position in self
and returns self
. The value of position
should have been returned from an earlier call to #tell; if not, the return values from subsequent calls to #read are unspecified.
See
.Dir
As Stream-Like
Examples:
dir = Dir.new('example')
dir.pos # => 0
dir.seek(3) # => #<Dir:example>
dir.pos # => 3
dir.seek(30) # => #<Dir:example>
dir.pos # => 5
# File 'dir.c', line 932
static VALUE dir_seek(VALUE dir, VALUE pos) { struct dir_data *dirp; long p = NUM2LONG(pos); GetDIR(dir, dirp); seekdir(dirp->dir, p); return dir; }
Alias for #path.