—use
strict;
package
Probe::Perl;
{
$Probe::Perl::VERSION
=
'0.03'
;
}
# TODO: cache values derived from launching an external perl process
# TODO: docs refer to Config.pm and $self->{config}
use
Config;
use
File::Spec;
sub
new {
my
$class
=
shift
;
my
$data
=
shift
|| {};
return
bless
(
$data
,
$class
);
}
sub
config {
my
(
$self
,
$key
) = (
shift
,
shift
);
if
(
@_
) {
unless
(
ref
$self
) {
die
"Can't set config values via $self->config(). Use $self->new() to create a local view"
;
}
$self
->{
$key
} =
shift
;
}
return
ref
(
$self
) &&
exists
$self
->{
$key
} ?
$self
->{
$key
} :
$Config
{
$key
};
}
sub
config_revert {
my
$self
=
shift
;
die
"Can't use config_revert() as a class method"
unless
ref
(
$self
);
delete
$self
->{
$_
}
foreach
@_
;
}
sub
perl_version {
my
$self
=
shift
;
# Check the current perl interpreter
# It's much more convenient to use $] here than $^V, but 'man
# perlvar' says I'm not supposed to. Bloody tyrant.
return
$^V ?
$self
->perl_version_to_float(
sprintf
(
"%vd"
, $^V )) : $];
}
sub
perl_version_to_float {
my
(
$self
,
$version
) =
@_
;
$version
=~ s/\./../;
# Double up the first dot so the output has one dot remaining
$version
=~ s/\.(\d+)/
sprintf
(
'%03d'
, $1 )/eg;
return
$version
;
}
sub
_backticks {
my
$perl
=
shift
;
return
unless
-e
$perl
;
my
$fh
;
eval
{
open
$fh
,
'-|'
,
$perl
,
@_
or
die
$!};
if
(!$@) {
return
<
$fh
>
if
wantarray
;
my
$tmp
=
do
{
local
$/=
undef
; <
$fh
>};
return
$tmp
;
}
# Quoting only happens on the path to perl - I control the rest of
# the args and they don't need quoting.
if
($^O eq
'MSWin32'
) {
$perl
=
qq{"$perl"}
if
$perl
=~ m{^[\w\\]+$};
}
else
{
$perl
=~ s{([^\w\\])}{\\$1}g;
}
return
`
$perl
@_
`;
}
sub
perl_is_same {
my
(
$self
,
$perl
) =
@_
;
return
_backticks(
$perl
,
qw(-MConfig=myconfig -e print -e myconfig)
) eq Config->myconfig;
}
sub
find_perl_interpreter {
my
$self
=
shift
;
return
$^X
if
File::Spec->file_name_is_absolute($^X);
my
$exe
=
$self
->config(
'exe_ext'
);
my
$thisperl
= $^X;
if
(
$self
->os_type eq
'VMS'
) {
# VMS might have a file version at the end
$thisperl
.=
$exe
unless
$thisperl
=~ m/
$exe
(;\d+)?$/i;
}
elsif
(
defined
$exe
) {
$thisperl
.=
$exe
unless
$thisperl
=~ m/
$exe
$/i;
}
foreach
my
$perl
(
$self
->config(
'perlpath'
),
map
( File::Spec->catfile(
$_
,
$thisperl
),
File::Spec->path() )
) {
return
$perl
if
-f
$perl
and
$self
->perl_is_same(
$perl
);
}
return
;
}
# Determine the default @INC for this Perl
sub
perl_inc {
my
$self
=
shift
;
local
$ENV
{PERL5LIB};
# this is not considered part of the default.
my
$perl
=
$self
->find_perl_interpreter();
my
@inc
= _backticks(
$perl
,
qw(-l -e print -e for -e @INC)
);
chomp
@inc
;
return
@inc
;
}
{
my
%OSTYPES
=
qw(
aix Unix
bsdos Unix
dgux Unix
dynixptx Unix
freebsd Unix
linux Unix
hpux Unix
irix Unix
darwin Unix
machten Unix
next Unix
openbsd Unix
netbsd Unix
dec_osf Unix
svr4 Unix
svr5 Unix
sco_sv Unix
unicos Unix
unicosmk Unix
solaris Unix
sunos Unix
cygwin Unix
os2 Unix
dos Windows
MSWin32 Windows
os390 EBCDIC
os400 EBCDIC
posix-bc EBCDIC
vmesa EBCDIC
MacOS MacOS
VMS VMS
VOS VOS
riscos RiscOS
amigaos Amiga
mpeix MPEiX
)
;
sub
os_type {
my
$class
=
shift
;
return
$OSTYPES
{
shift
|| $^O};
}
}
1;
__END__
=head1 NAME
Probe::Perl - Information about the currently running perl
=head1 VERSION
version 0.03
=head1 SYNOPSIS
use Probe::Perl;
$p = Probe::Perl->new();
# Version of this perl as a floating point number
$ver = $p->perl_version();
$ver = Probe::Perl->perl_version();
# Convert a multi-dotted string to a floating point number
$ver = $p->perl_version_to_float($ver);
$ver = Probe::Perl->perl_version_to_float($ver);
# Check if the given perl is the same as the one currently running
$bool = $p->perl_is_same($perl_path);
$bool = Probe::Perl->perl_is_same($perl_path);
# Find a path to the currently-running perl
$path = $p->find_perl_interpreter();
$path = Probe::Perl->find_perl_interpreter();
# Get @INC before run-time additions
@paths = $p->perl_inc();
@paths = Probe::Perl->perl_inc();
# Get the general type of operating system
$type = $p->os_type();
$type = Probe::Perl->os_type();
# Access Config.pm values
$val = $p->config('foo');
$val = Probe::Perl->config('foo');
$p->config('foo' => 'bar'); # Set locally
$p->config_revert('foo'); # Revert
=head1 DESCRIPTION
This module provides methods for obtaining information about the
currently running perl interpreter. It originally began life as code
in the C<Module::Build> project, but has been externalized here for
general use.
=head1 METHODS
=over 4
=item new()
Creates a new Probe::Perl object and returns it. Most methods in
the Probe::Perl packages are available as class methods, so you
don't always need to create a new object. But if you want to create a
mutable view of the C<Config.pm> data, it's necessary to create an
object to store the values in.
=item config( $key [, $value] )
Returns the C<Config.pm> value associated with C<$key>. If C<$value>
is also specified, then the value is set to C<$value> for this view of
the data. In this case, C<config()> must be called as an object
method, not a class method.
=item config_revert( $key )
Removes any user-assigned value in this view of the C<Config.pm> data.
=item find_perl_interpreter( )
Returns the absolute path of this perl interpreter. This is actually
sort of a tricky thing to discover sometimes - in these cases we use
C<perl_is_same()> to verify.
=item perl_version( )
Returns the version of this perl interpreter as a perl-styled version
number using C<perl_version_to_float()>. Uses C<$^V> if your perl is
recent enough, otherwise uses C<$]>.
=item perl_version_to_float( $version )
Formats C<$version> as a perl-styled version number like C<5.008001>.
=item perl_is_same( $perl )
Given the name of a perl interpreter, this method determines if it has
the same configuration as the one represented by the current perl
instance. Usually this means it's exactly the same
=item perl_inc( )
Returns a list of directories in this perl's C<@INC> path, I<before>
any entries from C<use lib>, C<$ENV{PERL5LIB}>, or C<-I> switches are
added.
=item os_type( [$osname] )
Returns a generic OS type (e.g. "Unix", "Windows", "MacOS") for the
given OS name. If no OS name is given it uses the value in $^O, which
is the same as $Config{osname}.
=back
=head1 AUTHOR
Randy W. Sims <randys@thepierianspring.org>
Based partly on code from the Module::Build project, by Ken Williams
<kwilliams@cpan.org> and others.
=head1 COPYRIGHT
Copyright 2005 Ken Williams and Randy Sims. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut