I was doing some work on Parrot::Test today and was replacing this code
with something more cross platform.

        # Run the command in a different directory
        my $command = 'some command';
        $command    = "cd $dir && $command" if $dir;
        system($command);

I replaced it with this.

        my $orig_dir = cwd;
        chdir $dir if $dir;
        system $command;
        chdir $orig_dir;

Go into some new directory temporarily, run something, go back to the
original.

Hmm.  Set a global to a new value temporarily and then return to the
original value.  Sounds a lot like local.  So why not use it?

        {
                local chdir $dir if $dir;
                system $command;
        }

But localizing a function call makes no sense, especially if it has side
effects.  Well, the current working directory is just a filepath.  Scalar
data.  Why have a function to change a scalar?  Just change it directly.
Now local() makes perfect sense.

        {
                local $CWD = $dir if $dir;
                system $command;
        }

And this is exactly what File::chdir does.  $CWD is a tied scalar.
Changing it changes the current working directory.  Reading it tells you
what the current working directory is.  Localizing it allows you to
safely change the cwd temporarily, for example within the scope of a
subroutine.  It eliminates both chdir() and cwd().

Error handling is simple, a failed chdir returns undef and sets errno.

        $CWD = $dir err die "Can't chdir to $dir: $!";

I encourage Perl 6 to adapt $*CWD similar to File::chdir and simply eliminate
chdir() and cwd().  They're just an unlocalizable store and fetch for global
data.

As a matter of fact, Autrijus is walking me through implementing it in Pugs
right now.

Reply via email to