Description: |
I like to read the code of modules I have installed, but, especially
when I use CPAN I never quite know when they are (and I am
lazy!).
So this tool gets a module name (or the end part of a
module name) and looks for it within @INC. Once it's
found it it pages it.
A few additional refinements, you can just list the files,
choose between multiple results and run the pager in
batch (I like textedit)
A nice improvement would be to get the DIRSEP character
automagically... |
#!/usr/perl -w
use strict;
use File::Find; # to find the source
use Getopt::Long; # to process options
use Pod::Usage; # generate usage from pod
# you can change those if needed
my $pager= 'less';
my $DIRSEP='/';
my $batch= ''; # will get & if batch mode required
my ( $list, $help); # other options
my %found; # valid module files (a hash so we get only one o
+f each)
GetOptions( "pager:s" => \$pager,
"batch" => sub { $batch= '&' },
"list" => \$list,
"help" => \$help,
) or pod2usage(2);
pod2usage(1) if $help;
my $module= shift || pod2usage(2); # get the module na
+me
pod2usage(2) if( @ARGV);
$module .= '.pm' unless $module=~ /\.pm$/; # add .pm if needed
$module=~ s{(::|-)}{$DIRSEP}g; # replace :: or - b
+y /
find( { wanted => \&wanted, no_chdir => 1}, @INC); # go get the file f
+rom @INC
my @found= keys %found; # get unique files
unless( @found) # nothing found, ex
+it
{ print "no source found for $module\n"; }
elsif( @found == 1) # found one:
{ my $file= shift @found;
if( $list)
{ print "$module in $file\n"; } # list files
else # or
{ system" $pager $file $batch"; } # page file
}
else
{ my $i;
if( $list)
{ print "found several candidates: \n",
map { " [@{[++$i]}] $_\n"} @found;
}
else
{ unshift @found, "quit";
print "found several candidates: \n",
map { " [@{[$i++]}] $_\n"} @found;
# use Term::ReadLine to get the exact module index
require Term::ReadLine;
import Term::ReadLine;
# get user input
my $term = Term::ReadLine->new('vmod');
my $prompt= '> ';
my $index= $term->readline($prompt);
exit unless( $index=~ /^\d+$/); # make sure we have a n
+umber
if( ($index > 0) && ($index<@found) ) # if it's a valid numbe
+r
{ my $file= $found[$index]; # get the file
system" $pager $file $batch"; # page it
}
}
}
exit;
# called for each file in the @INC forest
sub wanted
{ return unless( m/$module$/i);
$found{$_}= 1; # store file name in %fo
+und
}
__END__
=head1 NAME
vmod - a tool to display or page Perl modules
if several modules are found then a choice is given
=head1 SYNOPSIS
viewmod [options] [file]
file is the name of the module, with or without the .pm extension
levels can be separated by '::', '/', '-' or the native directo
+ry
separator
Options:
--help -h display this message
--pager -p pager/editor to use (defaults to less)
--batch -b run the pager in batch mode (with -p textedit for
+example)
--list -l only display the directory in which the source is
Re: vmod
by chipmunk (Parson) on Dec 02, 2000 at 23:20 UTC
|
To do the conversion from module name to file path in a platform independent way, I suggest the File::Spec module, which is part of the core distribution. This will create a path appropriate for whatever system the code happens to be running on:
use File::Spec;
my @module = split /::|-/, $module;
$module = File::Spec->catfile(@module);
(Note: much of the documentation for File::Spec is actually, and unfortunately, in the File::Spec::Unix module. I haven't found that documentation on this site, so you'll have to read it on your local system.) | [reply] [d/l] |
|