<?xml version="1.0" encoding="windows-1252"?>
<node id="44575" title="vmod" created="2000-12-02 17:23:22" updated="2005-07-27 14:20:27">
<type id="1980">
snippet</type>
<author id="9346">
mirod</author>
<data>
<field name="doctext">
</field>
<field name="snippetdesc">
&lt;p&gt;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!).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;A few additional refinements, you can just list the files,
   choose between multiple results and run the pager in 
   batch (I like textedit)&lt;/p&gt;
&lt;p&gt;A nice improvement would be to get the DIRSEP character
   automagically... &lt;/p&gt;</field>
<field name="snippetcode">
&lt;CODE&gt;
#!/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 &amp; if batch mode required
my ( $list, $help);  # other options
my %found;           # valid module files (a hash so we get only one of each)

GetOptions( "pager:s"        =&gt; \$pager,
            "batch"          =&gt; sub { $batch= '&amp;' },
            "list"           =&gt; \$list,
            "help"           =&gt; \$help,
          ) or pod2usage(2);

pod2usage(1) if $help;

my $module= shift || pod2usage(2);                 # get the module name
pod2usage(2) if( @ARGV);

$module .= '.pm' unless $module=~ /\.pm$/;         # add .pm if needed
$module=~ s{(::|-)}{$DIRSEP}g;                     # replace :: or - by /

find( { wanted =&gt; \&amp;wanted, no_chdir =&gt; 1}, @INC); # go get the file from @INC

my @found= keys %found;                            # get unique files

unless( @found)                                    # nothing found, exit
  { 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-&gt;new('vmod');
        my $prompt= '&gt; ';
        my $index= $term-&gt;readline($prompt);

        exit unless( $index=~ /^\d+$/);        # make sure we have a number

        if( ($index &gt; 0) &amp;&amp; ($index&lt;@found) )  # if it's a valid number
          { 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 %found
  }

__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 directory
       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




&lt;/CODE&gt;</field>
</data>
</node>
