The dir routine

Combined from primary sources listed below.

In class IO::Spec::Win32 ( type/IO/Spec/Win32 )§

See primary docmentation in context for method dir.

method dir-sep§

method dir-sep(--> Str:D)

Returns the string 「\」 representing canonical directory separator character.

IO::Spec::Win32.dir-sep.say# OUTPUT: «\␤»

In class IO::Spec::Unix ( type/IO/Spec/Unix )§

See primary docmentation in context for method dir.

method dir-sep§

method dir-sep(--> Str:D)

Returns the string "/" representing canonical directory separator character.

IO::Spec::Unix.dir-sep.say# OUTPUT: «/␤»

In class IO::Path ( type/IO/Path )§

See primary docmentation in context for routine dir.

routine dir§

multi  dir(*%_)
multi  dir(IO::Path:D $path, |c)
multi  dir(IO()       $path, |c)
method dir(IO::Path:D: Mu :$test = $*SPEC.curupdir)

Returns a lazy list of IO::Path objects corresponding to the entries in a directory, optionally filtered by smartmatching their names as strings per the :test parameter. The order in which the filesystem returns entries determines the order of the entries/objects in the list. Objects corresponding to special directory entries . and .. are not included. $path determines whether the objects' paths are absolute or relative.

Since the tests are performed against Str arguments, not IO, the tests are executed in the $*CWD, instead of the target directory. When testing against file test operators, this won't work:

dir('mydir', test => { .IO.d })

while this will:

dir('mydir', test => { "mydir/$_".IO.d })

NOTE: a dir call opens a directory for reading, which counts towards maximum per-process open files for your program. Be sure to exhaust returned Seq before doing something like recursively performing more dir calls. You can exhaust it by assigning to an @-sigiled variable or simply looping over it. Note how examples below push further dirs to look through into an Array, rather than immediately calling dir on them. See also IO::Dir module that gives you finer control over closing dir handles.

Examples:

# To iterate over the contents of the current directory:
for dir() -> $file {
    say $file;
}

# As before, but include even '.' and '..' which are filtered out by
# the default :test matcher:
for dir(test => *-> $file {
    say $file;
}

# To get the names of all .jpg and .jpeg files in the home directory of the current user:
my @jpegs = $*HOME.dir: test => /:i '.' jpe?g $/;

An example program that lists all files and directories recursively:

sub MAIN($dir = '.') {
    my @todo = $dir.IO;
    while @todo {
        for @todo.pop.dir -> $path {
            say $path.Str;
            @todo.push: $path if $path.d;
        }
    }
}

A lazy way to find the first three files ending in ".raku" recursively starting from the current directory:

my @stack = '.'.IO;
my $raku-files = gather while @stack {
    with @stack.pop {
        when :d { @stack.append: .dir }
        .take when .extension.lc eq 'raku'
    }
}
.put for $raku-files[^3];

In class IO::Path ( type/IO/Path )§

See primary docmentation in context for method dir.

method dir-with-entries§

Available as of the 2022.04 Rakudo compiler release.

Returns a Bool indicating whether the path is a directory with any entries in it. Throws an exception if the path is not a directory, or the path doesn't exist.

say "'$_' has entries" if .d && .dir-with-entries given "path/to/dir".IO;