Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

vmod

by mirod (Canon)
on Dec 02, 2000 at 22:23 UTC ( #44575=snippet: print w/replies, xml ) Need Help??
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
Replies are listed 'Best First'.
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.)
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: snippet [id://44575]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (8)
As of 2023-09-28 10:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?