class Dir - Documentation for Ruby 4.0
Description: class Dir: An object of class \Dir represents a directory in the underlying file system. A string _path_, given when the object is created, that specifies a di
Keywords: ruby,class,Dir

🔍

No recent searches

# class Dir

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:

- 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 `Dir.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:

- 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

- `::[]`: 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`.

### Public Class Methods

Dir[*patterns, base: nil, sort: true] → array
Source

    # File dir.rb, line 222
    def self.[](*args, base: nil, sort: true)
      Primitive.dir_s_aref(args, base, sort)
    end

Calls `Dir.glob` with argument `patterns` and the values of keyword arguments `base` and `sort`; returns the array of selected entry names.

chdir(new_dirpath) → 0
chdir → 0
chdir(new_dirpath) {|new_dirpath| ... } → object
chdir {|cur_dirpath| ... } → object
Source

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

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.

children(dirpath) → array
children(dirpath, encoding: 'UTF-8') → array
Source

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

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.

chroot(dirpath) → 0
Source

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

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.

rmdir(dirpath) → 0
Source

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

Removes the directory at `dirpath` from the underlying file system:

    Dir.rmdir('foo') # => 0

Raises an exception if the directory is not empty.

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

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

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

empty?(dirpath) → true or false
Source

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

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.

entries(dirname, encoding: 'UTF-8') → array
Source

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

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.

exist?(dirpath) → true or false
Source

    VALUE
    rb_file_directory_p(void)
    {
    }

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

fchdir(fd) → 0
fchdir(fd) { ... } → object
Source

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

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

for_fd(fd) → dir
Source

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

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

foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } → nil
Source

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

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.

pwd → string
Source

    static VALUE
    dir_s_getwd(VALUE dir)
    {
        return rb_dir_getwd();
    }

Returns the path to the current working directory:

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

glob(patterns, flags: 0, base: nil, sort: true) → array
glob(patterns, flags: 0, base: nil, sort: true) {|entry_name| ... } → nil
Source

    # File dir.rb, line 410
    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

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 a Regexp 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 like Regexp 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, use `Dir['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.

home(user_name = nil) → dirpath
Source

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

    }

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.

mkdir(dirpath, permissions = 0775) → 0
Source

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

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.

mktmpdir (prefix_suffix=nil, *rest, **options) { |dup| ... }
Source

    # File lib/tmpdir.rb, line 97
    def self.mktmpdir(prefix_suffix=nil, *rest, **options, &block)
      base = nil
      path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|path, _, _, d|
        base = d
        mkdir(path, 0700)
      }
      if block
        begin
          yield path.dup
        ensure
          unless base
            base = File.dirname(path)
            stat = File.stat(base)
            if stat.world_writable? and !stat.sticky?
              raise ArgumentError, "parent directory is world writable but not sticky: #{base}"
            end
          end
          FileUtils.remove_entry path
        end
      else
        path
      end
    end

`Dir.mktmpdir` creates a temporary directory.

    require 'tmpdir'
    Dir.mktmpdir {|dir|
      # use the directory
    }

The directory is created with 0700 permission. Application should not change the permission to make the temporary directory accessible from other users.

The prefix and suffix of the name of the directory is specified by the optional first argument, prefix_suffix.

- If it is not specified or nil, “d” is used as the prefix and no suffix is used.

- If it is a string, it is used as the prefix and no suffix is used.

- If it is an array, first element is used as the prefix and second element is used as a suffix.

    Dir.mktmpdir {|dir| dir is ".../d..." }
    Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
    Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }

The directory is created under `Dir.tmpdir` or the optional second argument tmpdir if non-nil value is given.

    Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
    Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }

If a block is given, it is yielded with the path of the directory. The directory and its contents are removed using `FileUtils.remove_entry` before `Dir.mktmpdir` returns. The value of the block is returned.

    Dir.mktmpdir {|dir|
      # use the directory...
      open("#{dir}/foo", "w") { something using the file }
    }

If a block is not given, The path of the directory is returned. In this case, `Dir.mktmpdir` doesn’t remove the directory.

    dir = Dir.mktmpdir
    begin
      # use the directory...
      open("#{dir}/foo", "w") { something using the file }
    ensure
      # remove the directory.
      FileUtils.remove_entry dir
    end

new(dirpath) → dir
new(dirpath, encoding: nil) → dir
Source

    # File dir.rb, line 211
    def initialize(name, encoding: nil)
      Primitive.dir_initialize(name, encoding)
    end

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>

open(dirpath) → dir
open(dirpath, encoding: nil) → dir
open(dirpath) {|dir| ... } → object
open(dirpath, encoding: nil) {|dir| ... } → object
Source

    # 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

Creates a new Dir object dir for the directory at `dirpath`.

With no block, the method equivalent to `Dir.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>

pwd → string
Source

    static VALUE
    dir_s_getwd(VALUE dir)
    {
        return rb_dir_getwd();
    }

Returns the path to the current working directory:

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

rmdir(dirpath) → 0
Source

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

Removes the directory at `dirpath` from the underlying file system:

    Dir.rmdir('foo') # => 0

Raises an exception if the directory is not empty.

tmpdir ()
Source

    # File lib/tmpdir.rb, line 25
    def self.tmpdir
      Tmpname::TMPDIR_CANDIDATES.find do |name, dir|
        unless dir
          next if !(dir = ENV[name] rescue next) or dir.empty?
        end
        dir = File.expand_path(dir)
        stat = File.stat(dir) rescue next
        case
        when !stat.directory?
          warn "#{name} is not a directory: #{dir}"
        when !File.writable?(dir)
          # We call File.writable?, not stat.writable?, because you can't tell if a dir is actually
          # writable just from stat; OS mechanisms other than user/group/world bits can affect this.
          warn "#{name} is not writable: #{dir}"
        when stat.world_writable? && !stat.sticky?
          warn "#{name} is world-writable: #{dir}"
        else
          break dir
        end
      end or raise ArgumentError, "could not find a temporary directory"
    end

Returns the operating system’s temporary file path.

    require 'tmpdir'
    Dir.tmpdir # => "/tmp"

rmdir(dirpath) → 0
Source

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

Removes the directory at `dirpath` from the underlying file system:

    Dir.rmdir('foo') # => 0

Raises an exception if the directory is not empty.

### Public Instance Methods

chdir → 0
chdir { ... } → object
Source

    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
    }

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 `Dir.fchdir` if available, and `Dir.chdir` if not, see those methods for caveats.

children → array
Source

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

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

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

close → nil
Source

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

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.

each {|entry_name| ... } → self
Source

    static VALUE
    dir_each(VALUE dir)
    {
        RETURN_ENUMERATOR(dir, 0, 0);
        return dir_each_entry(dir, dir_yield, Qnil, FALSE);
    }

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

each_child {|entry_name| ... } → self
Source

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

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.

fileno → integer
Source

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

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

inspect → string
Source

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

Returns a string description of `self`:

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

path → string or nil
Source

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

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

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

Also aliased as: to_path
pos
Alias for: tell
pos = position → integer
Source

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

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

read → string or nil
Source

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

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"

rewind → self
Source

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

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

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

seek(position) → self
Source

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

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

tell → integer
Source

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

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

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

Also aliased as: pos
to_path
Alias for: path