Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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




Comment on vmod
Download Code
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.)

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
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 imbibing at the Monastery: (6)
As of 2015-05-06 04:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    In my home, the TV remote control is ...









    Results (130 votes), past polls