9999our @EXPORT = ' which' ;
100100our @EXPORT_OK = ' where' ;
101101
102- use constant IS_VMS => ($^O eq ' VMS' );
103- use constant IS_MAC => ($^O eq ' MacOS' );
104- use constant IS_WIN => ($^O eq ' MSWin32' or $^O eq ' dos' or $^O eq ' os2' );
105- use constant IS_DOS => IS_WIN();
106- use constant IS_CYG => ($^O eq ' cygwin' || $^O eq ' msys' );
107-
108- our $IMPLICIT_CURRENT_DIR = IS_WIN || IS_VMS || IS_MAC;
109-
110- # For Win32 systems, stores the extensions used for
111- # executable files
112- # For others, the empty string is used
113- # because 'perl' . '' eq 'perl' => easier
114- my @PATHEXT = (' ' );
115- if ( IS_WIN ) {
116- # WinNT. PATHEXT might be set on Cygwin, but not used.
117- if ( $ENV {PATHEXT } ) {
118- push @PATHEXT , split /;/, $ENV {PATHEXT };
119- } else {
120- # Win9X or other: doesn't have PATHEXT, so needs hardcoded.
121- push @PATHEXT , qw{ .com .exe .bat} ;
102+ sub _get_osname { @_ == 1 && ref $_ [0] ? $_ [0]-> {osname } : $^O }
103+
104+ sub IS_VMS { my $osname = &_get_osname; ($osname eq ' VMS' ); }
105+ sub IS_MAC { my $osname = &_get_osname; ($osname eq ' MacOS' ); }
106+ sub IS_WIN { my $osname = &_get_osname; ($osname eq ' MSWin32' or $osname eq ' dos' or $osname eq ' os2' ); }
107+ sub IS_DOS { IS_WIN(@_ ); }
108+ sub IS_CYG { my $osname = &_get_osname; ($osname eq ' cygwin' || $osname eq ' msys' ); }
109+
110+ sub _default_IMPLICIT_CURRENT_DIR {
111+ my $self = shift ;
112+ $self -> IS_WIN || $self -> IS_VMS || $self -> IS_MAC;
113+ }
114+ our $IMPLICIT_CURRENT_DIR = do {
115+ File::Which-> new-> _default_IMPLICIT_CURRENT_DIR;
116+ };
117+
118+ sub new {
119+ my ($class , %opts ) = @_ ;
120+
121+ my $osname = exists $opts {os } ? $opts {os } : $^O;
122+
123+ my $self = bless {
124+ osname => $osname ,
125+ }, $class ;
126+
127+ $self -> {IMPLICIT_CURRENT_DIR } =
128+ exists $opts {IMPLICIT_CURRENT_DIR }
129+ ? $opts {IMPLICIT_CURRENT_DIR }
130+ : $self -> _default_IMPLICIT_CURRENT_DIR;
131+
132+ $self -> {PATHEXT } = $self -> _default_pathext;
133+
134+ $self ;
135+ }
136+
137+ sub _default_pathext {
138+ my $self = shift ;
139+ # For Win32 systems, stores the extensions used for
140+ # executable files
141+ # For others, the empty string is used
142+ # because 'perl' . '' eq 'perl' => easier
143+ my @PATHEXT = (' ' );
144+ if ( $self -> IS_WIN ) {
145+ # WinNT. PATHEXT might be set on Cygwin, but not used.
146+ if ( $ENV {PATHEXT } ) {
147+ push @PATHEXT , split /;/, $ENV {PATHEXT };
148+ } else {
149+ # Win9X or other: doesn't have PATHEXT, so needs hardcoded.
150+ push @PATHEXT , qw{ .com .exe .bat} ;
151+ }
152+ } elsif ( $self -> IS_VMS ) {
153+ push @PATHEXT , qw{ .exe .com} ;
154+ } elsif ( $self -> IS_CYG ) {
155+ # See this for more info
156+ # http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-exe
157+ push @PATHEXT , qw{ .exe .com} ;
122158 }
123- } elsif ( IS_VMS ) {
124- push @PATHEXT , qw{ .exe .com} ;
125- } elsif ( IS_CYG ) {
126- # See this for more info
127- # http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-exe
128- push @PATHEXT , qw{ .exe .com} ;
159+
160+ \@PATHEXT ;
129161}
130162
131163=head1 FUNCTIONS
@@ -152,6 +184,13 @@ matches.
152184=cut
153185
154186sub which {
187+ my $self = @_ == 1
188+ ? File::Which-> new(
189+ # Use global to retain compatibility, but only for the functional
190+ # interface.
191+ IMPLICIT_CURRENT_DIR => $IMPLICIT_CURRENT_DIR ,
192+ )
193+ : shift ;
155194 my ($exec ) = @_ ;
156195
157196 return undef unless defined $exec ;
@@ -161,15 +200,15 @@ sub which {
161200 my @results = ();
162201
163202 # check for aliases first
164- if ( IS_VMS ) {
203+ if ( $self -> IS_VMS ) {
165204 my $symbol = ` SHOW SYMBOL $exec ` ;
166205 chomp ($symbol );
167206 unless ( $? ) {
168207 return $symbol unless $all ;
169208 push @results , $symbol ;
170209 }
171210 }
172- if ( IS_MAC ) {
211+ if ( $self -> IS_MAC ) {
173212 my @aliases = split /\,/, $ENV {Aliases };
174213 foreach my $alias ( @aliases ) {
175214 # This has not been tested!!
@@ -188,10 +227,10 @@ sub which {
188227 }
189228
190229 return $exec # # no critic (ValuesAndExpressions::ProhibitMixedBooleanOperators)
191- if !IS_VMS and !IS_MAC and !IS_WIN and $exec =~ / \/ / and -f $exec and -x $exec ;
230+ if !$self -> IS_VMS and !$self -> IS_MAC and !$self -> IS_WIN and $exec =~ / \/ / and -f $exec and -x $exec ;
192231
193232 my @path ;
194- if ($^O eq ' MSWin32' ) {
233+ if ($self -> { osname } eq ' MSWin32' ) {
195234 # File::Spec (at least recent versions)
196235 # add the implicit . for you on MSWin32,
197236 # but we may or may not want to include
@@ -202,10 +241,11 @@ sub which {
202241 } else {
203242 @path = File::Spec-> path;
204243 }
205- if ( $IMPLICIT_CURRENT_DIR ) {
244+ if ( $self -> { IMPLICIT_CURRENT_DIR } ) {
206245 unshift @path , File::Spec-> curdir;
207246 }
208247
248+ my @PATHEXT = @{ $self -> {PATHEXT } };
209249 foreach my $base ( map { File::Spec-> catfile($_ , $exec ) } @path ) {
210250 for my $ext ( @PATHEXT ) {
211251 my $file = $base .$ext ;
@@ -218,10 +258,10 @@ sub which {
218258 -x _
219259 or (
220260 # MacOS doesn't mark as executable so we check -e
221- IS_MAC # # no critic (ValuesAndExpressions::ProhibitMixedBooleanOperators)
261+ $self -> IS_MAC # # no critic (ValuesAndExpressions::ProhibitMixedBooleanOperators)
222262 ||
223263 (
224- ( IS_WIN or IS_CYG )
264+ ( $self -> IS_WIN or $self -> IS_CYG )
225265 and
226266 grep { # # no critic (BuiltinFunctions::ProhibitBooleanGrep)
227267 $file =~ / $_ \z /i
0 commit comments