This is cross-posted here from Israel.pm where I have yet to receive an answer.
I'm trying to process the directory components of a path (as an array) so that:
If the processing is to keep only the directories after "long-dir" then:
/hello/there/long-dir/another/myfile.txt ==> another/myfile.txt
DOS : C:\Hello\There\Long-Dir\Another\myfile.txt ==> another\myfile.txt
./hi/long-dir/another/myfile.txt ==> another/myfile.txt
.\hi\long-dir\another\myfile.txt ==> another\myfile.txt
To do this I turned to File::Spec and File::Basename and wrote the following code which seems insanely complicated. I marked the place where I do the actual processing using a callback:
my ($self, $fn, $callback) = @_;
my $basename = basename($fn);
my $dirpath = dirname($fn);
my ($volume, $directories, $filename) = File::Spec->splitpath($dirpath,
# The actual manipulation.
my $dirs = $callback->([File::Spec->splitdir($directories)]);
my $final_dir =
$volume, File::Spec->catdir(@$dirs), $filename
if ($final_dir eq "")
And so far I checked it works only on UNIXes (Linux in my case) and on relative paths.
So my questions are:
I should note that this hairiness is not limited to Perl. Common Lisp has a built-in portable path-manipulation abstraction that's also relatively complicated. See the "File and File I/O Chapter" and the a Portable Pathname library chapter