123456789_123456789_123456789_123456789_123456789_

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 a stream-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:

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 #tell (aliased as #pos) returns the position.
  • ::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:

Here, class Dir provides methods that are useful for:

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

  • .[]: Same as .glob without the ability to pass flags.
  • .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

Instance Attribute Summary

Instance Method Summary

::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
#compact

Returns an array of all non-+nil+ elements:

#count

Returns the count of elements, based on an argument or block criterion, if given.

#cycle

When called with positive integer argument n and a block, calls the block with each element, then does so again, until it has done so n times; returns nil:

#detect

Alias for Enumerable#find.

#drop

For positive integer n, returns an array containing all but the first n elements:

#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 +n+-tuple of elements; returns self:

#each_entry

Calls the given block with each element, converting multiple values from yield to an array; returns self:

#each_slice

Calls the block with each successive disjoint +n+-tuple of elements; returns self:

#each_with_index

Invoke self.each with *args.

#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
#find_index

Returns the index of the first element that meets a specified criterion, or nil if no such element is found.

#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 self that match the given pattern.

#grep_v

Returns an array of objects based on elements of self that don't match the given pattern.

#group_by

With a block given returns a hash:

#include?
#inject

Returns the result of applying a reducer to an initial value and the first element of the ::Enumerable.

#lazy

Returns an ::Enumerator::Lazy, which redefines most ::Enumerable methods to postpone enumeration and enumerate values only on an as-needed basis.

#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 object == 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
#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 self:

#select
#slice_after

Creates an enumerator for each chunked elements.

#slice_before

With argument pattern, returns an enumerator that uses the pattern to partition elements into arrays ("slices").

#slice_when

Creates an enumerator for each chunked elements.

#sort

Returns an array containing the sorted elements of self.

#sort_by

With a block given, returns an array of elements of self, sorted according to the value returned by the block for each element.

#sum

With no block given, returns the sum of initial_value and the elements:

#take

For non-negative integer n, returns the first n elements:

#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

When argument hash is not given, returns a new hash whose keys are the distinct elements in self; each integer value is the count of occurrences of each element:

#to_a

Returns an array containing the items in self:

#to_h

When self consists of 2-element arrays, returns a hash each of whose entries is the key-value pair formed from one of those arrays:

#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 e0 and e1 such that e0.eql?(e1):

#zip

With no block given, returns a new array new_array of size self.size whose elements are arrays.

Constructor Details

.new(dirpath) ⇒ 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: Encoding::US_ASCI).read.encoding # => #<Encoding:US-ASCII>
[ GitHub ]

  
# 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

Like .glob, but does not accept keyword argument flags.

[ GitHub ]

  
# File 'dir.rb', line 219

def self.[](*args, base: nil, sort: true)
  Primitive.dir_s_aref(args, base, sort)
end

.chdir(new_dirpath) ⇒ 0 .chdir0 .chdir(new_dirpath) {|new_dirpath| ... } ⇒ Object .chdir {|cur_dirpath| ... } ⇒ Object

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.

[ GitHub ]

  
# File 'dir.c', line 1414

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);
}

.children(dirpath) ⇒ Array .children(dirpath, encoding: 'UTF-8') ⇒ 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:

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.

[ GitHub ]

  
# File 'dir.c', line 3773

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.

[ GitHub ]

  
# File 'dir.c', line 1715

static VALUE
dir_s_chroot(VALUE dir, VALUE path)
{
    path = check_dirname(path);
    if (IO_WITHOUT_GVL_INT(nogvl_chroot, (void *)RSTRING_PTR(path)) == -1)
        rb_sys_fail_path(path);

    return INT2FIX(0);
}

.rmdir(dirpath) ⇒ 0 .delete(dirpath) ⇒ 0

Alias for .rmdir.

.each_child(dirpath) {|entry_name| ... } ⇒ nil .each_child(dirpath, encoding: 'UTF-8') {|entry_name| ... } ⇒ nil

Like .foreach, except that entries '.' and '..' are not included.

[ GitHub ]

  
# File 'dir.c', line 3674

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.

[ GitHub ]

  
# File 'dir.c', line 3976

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,};
        struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, 0);
        if (gvl_getattrlist(&args, path) != 0)
            rb_sys_fail_path(orig);
        if (*(const fsobj_tag_t *)(attrbuf+1) == VT_HFS) {
            al.commonattr = 0;
            al.dirattr = ATTR_DIR_ENTRYCOUNT;
            if (gvl_getattrlist(&args, path) == 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)IO_WITHOUT_GVL(nogvl_dir_empty_p, (void *)path);
    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.

[ GitHub ]

  
# File 'dir.c', line 3651

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?.

[ GitHub ]

  
# File 'dir.c', line 3924

VALUE
rb_file_directory_p(void)
{
}

.fchdir(fd) ⇒ 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).

[ GitHub ]

  
# File 'dir.c', line 1530

static VALUE
dir_s_fchdir(VALUE klass, VALUE fd_value)
{
    int fd = RB_NUM2INT(fd_value);

    if (chdir_alone_block_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 = IO_WITHOUT_GVL_INT(nogvl_fchdir, &fd);
        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).

[ GitHub ]

  
# File 'dir.c', line 695

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 = IO_WITHOUT_GVL(nogvl_fdopendir, (void *)(VALUE)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"
".."
"."

::Encoding:

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.

[ GitHub ]

  
# File 'dir.c', line 3609

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;
}

.pwdString .getwdString

Alias for .pwd.

.glob(patterns, flags: 0, base: '.', sort: true) ⇒ array_of_entries

Returns an array of filesystem entries; see Filename Globbing.

[ GitHub ]

  
# File 'dir.rb', line 228

def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true)
  Primitive.attr! :use_block
  Primitive.dir_s_glob(pattern, flags, base, sort)
end

.home(user_name = nil) ⇒ Dir

Returns 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.

[ GitHub ]

  
# File 'dir.c', line 3890

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)) {
        StringValue(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; see File Permissions:

Dir.mkdir('foo')
File.stat(Dir.new('foo')).mode.to_s(8) # => "40775"
Dir.mkdir('bar', 0644)
File.stat(Dir.new('bar')).mode.to_s(8) # => "40644"
Dir.rmdir('foo')
Dir.rmdir('bar')

Argument permissions is ignored on Windows.

[ GitHub ]

  
# File 'dir.c', line 1758

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 = IO_WITHOUT_GVL_INT(nogvl_mkdir, &m);
    if (r < 0)
        rb_sys_fail_path(path);

    return INT2FIX(0);
}

.open(dirpath) ⇒ Dir .open(dirpath, encoding: nil) ⇒ Dir .open(dirpath) {|dir| ... } ⇒ Object .open(dirpath, encoding: nil) {|dir| ... } ⇒ Object

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: Encoding::US_ASCII).read.encoding # => #<Encoding:US-ASCII>
[ GitHub ]

  
# 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

.pwdString Also known as: .getwd

Returns the path to the current working directory:

Dir.chdir("/tmp") # => 0
Dir.pwd           # => "/tmp"
[ GitHub ]

  
# File 'dir.c', line 1670

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.

[ GitHub ]

  
# File 'dir.c', line 1799

static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
    const char *p;
    int r;

    dir = check_dirname(dir);
    p = RSTRING_PTR(dir);
    r = IO_WITHOUT_GVL_INT(nogvl_rmdir, (void *)p);
    if (r < 0)
        rb_sys_fail_path(dir);

    return INT2FIX(0);
}

.scan(dirpath) {|entry_name, entry_type| ... } ⇒ nil .scan(dirpath, encoding: 'UTF-8') {|entry_name, entry_type| ... } ⇒ nil .scan(dirpath) ⇒ Array, entry_type .scan(dirpath, encoding: 'UTF-8') ⇒ Array, entry_type

Yields or returns an array of the entry names in the directory at dirpath associated with their type, except for '.' and '..'; sets the given encoding onto each returned entry name.

The type symbol is one of: <code>:file</code>'', <code>:directory'', <code>:characterSpecial</code>'', <code>:blockSpecial'', <code>:fifo</code>'', <code>:link'', or ``<code>:socket'':

Dir.children('/example') # => [["config.h", :file], ["lib", :directory], ["main.rb", :file]]
Dir.children('/example').first.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.

[ GitHub ]

  
# File 'dir.c', line 3809

static VALUE
dir_s_scan(int argc, VALUE *argv, VALUE klass)
{
    VALUE dir = dir_open_dir(argc, argv);
    return rb_ensure(dir_scan_children, dir, dir_close, dir);
}

Instance Attribute Details

#posInteger (rw) Also known as: #tell

Returns the current position of self; see Dir As Stream-Like:

dir = Dir.new('example')
dir.tell  # => 0
dir.read  # => "."
dir.tell  # => 1
[ GitHub ]

  
# File 'dir.c', line 1101

static VALUE
dir_tell(VALUE dir)
{
    struct dir_data *dirp;
    long pos;

    GetDIR(dir, dirp);
    if((pos = telldir(dirp->dir)) < 0)
        rb_sys_fail("telldir");
    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
[ GitHub ]

  
# File 'dir.c', line 1172

static VALUE
dir_set_pos(VALUE dir, VALUE pos)
{
    dir_seek(dir, pos);
    return pos;
}

#posInteger (readonly) #tellInteger

Alias for #pos.

Instance Method Details

#chdir0 #chdirObject

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.

[ GitHub ]

  
# File 'dir.c', line 1578

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
}

#childrenArray

Returns an array of the entry names in self except for '.' and '..':

dir = Dir.new('/example')
dir.children # => ["config.h", "lib", "main.rb"]
[ GitHub ]

  
# File 'dir.c', line 3721

static VALUE
dir_collect_children(VALUE dir)
{
    VALUE ary = rb_ary_new();
    dir_each_entry(dir, dir_entry_ary_push, ary, TRUE);
    return ary;
}

#closenil

Closes the stream in self, if it is open, and returns nil; ignored if self is already closed:

dir = Dir.new('example')
dir.read     # => "."
dir.close     # => nil
dir.close     # => nil
dir.read # Raises IOError.
[ GitHub ]

  
# File 'dir.c', line 1221

static VALUE
dir_close(VALUE dir)
{
    struct dir_data *dirp;

    dirp = dir_get(dir);
    if (!dirp->dir) return Qnil;
    close_dir_data(dirp);

    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.

[ GitHub ]

  
# File 'dir.c', line 1044

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.

[ GitHub ]

  
# File 'dir.c', line 3703

static VALUE
dir_each_child_m(VALUE dir)
{
    RETURN_ENUMERATOR(dir, 0, 0);
    return dir_each_entry(dir, dir_yield, Qnil, TRUE);
}

#filenoInteger

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).

[ GitHub ]

  
# File 'dir.c', line 793

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);
}

#inspectString

Returns a string description of self:

Dir.new('example').inspect # => "#<Dir:example>"
[ GitHub ]

  
# File 'dir.c', line 748

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);
}

#pathString? Also known as: #to_path

Returns the dirpath string that was used to create self (or nil if created by method .for_fd):

Dir.new('example').path # => "example"
[ GitHub ]

  
# File 'dir.c', line 819

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);
}

#readString?

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"
[ GitHub ]

  
# File 'dir.c', line 904

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 */
    }
}

#rewindself

Sets the position in self to zero; see Dir As Stream-Like:

dir = Dir.new('example')
dir.read    # => "."
dir.read    # => ".."
dir.pos     # => 2
dir.rewind  # => #<Dir:example>
dir.pos     # => 0
[ GitHub ]

  
# File 'dir.c', line 1197

static VALUE
dir_rewind(VALUE dir)
{
    struct dir_data *dirp;

    GetDIR(dir, dirp);
    rewinddir(dirp->dir);
    return dir;
}

#childrenArray

Returns an array of the entry names in self along with their type except for '.' and '..':

dir = Dir.new('/example')
dir.scan # => [["config.h", :file], ["lib", :directory], ["main.rb", :file]]
[ GitHub ]

  
# File 'dir.c', line 3740

static VALUE
dir_scan_children(VALUE dir)
{
    if (rb_block_given_p()) {
        dir_each_entry(dir, dir_yield_with_type, Qnil, TRUE);
        return Qnil;
    }
    else {
        VALUE ary = rb_ary_new();
        dir_each_entry(dir, dir_yield_with_type, ary, TRUE);
        return ary;
    }
}

#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
[ GitHub ]

  
# File 'dir.c', line 1137

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;
}

#pathString? #to_pathString?

Alias for #path.