# input:
my $f = 'perl'; # for example
# output:
my @exec;
{
use File::Spec;
my @ext = split /;/, $ENV{PATHEXT} || '.exe;.com;.bat';
foreach my $p (File::Spec->path) {
push @exec, grep { -f and -x } map File::Spec->catfile($p, "$f$_"), '', @ext;
# You may leave the loop when something is found, if you only care about the first
}
@exec or die "Can't find executable $f";
}
# Show result:
{
local $\ = "\n";
print for @exec;
}
use File::Spec;
my @exec = map { my $p = $_; grep { -f and -x } map File::Spec->catfile($p, "$f$_"), '', qw(.exe .com .bat) } File::Spec->path
or die "Can't find executable $f";
Oh, and I found a bug in the module:
#!/usr/bin/perl -wl
use File::Which;
open OUT, '>complexe'; close OUT;
print for which('complexe');
which prints out
.\complexeThe author has forgotten to use [quotemeta]. The file name matches /.exe$/, but still, it's not a program file name.
grep { -f and -x }
You only need to stat the file once:
grep { -f and -x _ }
Your code also looks for 'complexe' (no extension) when asked to look for 'complexe' (because of the empty string you pass to map) so you have the same 'bug'. Your code doesn't output 'complexe' because '-x' compares the extension (again) for you.
You also suffer from a bug (or perhaps interface contract dispute) in (at least some versions of) File::Spec in that '.' is not returned from File::Spec->path() even though it is unconditionally searched first even if it isn't present in $ENV{PATH}. Perhaps File::Spec->path() is meant to (as documented) only return what is set in $ENV{PATH} rather than returning what would be more useful, the list of directories that would be searched when a command is entered. I'd rather this bug be fixed by updating File::Spec's implementation and documentation, however.
- tye
perlmonks.org content © perlmonks.org and bart, jwkrahn, salva, tye
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03