In Independent routines§

See primary documentation in context for sub indir

sub indir(IO() $path, &code, :$d = True, :$r, :$w, :$x)

Takes Callable &code and executes it after locally (to &code) changing $*CWD variable to an IO::Path object based on $path, optionally ensuring the new path passes several file tests. If $path is relative, it will be turned into an absolute path, even if an IO::Path object was given. NOTE: that this routine does NOT alter the process's current directory (see &*chdir). The $*CWD outside of the &code is not affected, even if &code explicitly assigns a new value to $*CWD.

Returns the value returned by the &code call on success. On failure to successfully change $*CWD, returns Failure. WARNING: keep in mind that lazily evaluated things might end up NOT having the $*CWD set by indir in their dynamic scope by the time they're actually evaluated. Either ensure the generators have their $*CWD set or eagerly evaluate them before returning the results from indir:

say indir("/tmp", {
    gather { take ".".IO }
})».CWD; # OUTPUT: «(/home/camelia)␤»

say indir("/tmp", {
    eager gather { take ".".IO }
})».CWD; # OUTPUT: «(/tmp)␤»

say indir("/tmp", {
    my $cwd = $*CWD;
    gather { temp $*CWD = $cwd; take ".".IO }
})».CWD; # OUTPUT: «(/tmp)␤»

The routine's $path argument can be any object with an IO method that returns an IO::Path object. The available file tests are:

  • :d — check .d returns True

  • :r — check .r returns True

  • :w — check .w returns True

  • :x — check .x returns True

By default, only :d test is performed.

say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤»
indir '/tmp', { say $*CWD }; # OUTPUT: «"/tmp".IO␤»
say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤»

indir '/not-there', {;};     # returns Failure; path does not exist