perl
view release on metacpan or search on metacpan
pod/perlmodlib.PL view on Meta::CPAN
#!../miniperl
use strict;
use warnings;
local $ENV{LC_ALL} = 'C';
my $Quiet;
@ARGV = grep { not($_ eq '-q' and $Quiet = 1) } @ARGV;
if (@ARGV) {
my $workdir = shift;
chdir $workdir
or die "Couldn't chdir to '$workdir': $!";
}
require './regen/regen_lib.pl';
# MANIFEST itself is Unix style filenames, so we have to assume that Unix style
# filenames will work.
open my $manifest_fh, '<', 'MANIFEST'
or die "Can't open MANIFEST: $!";
my @files =
grep !m#/perl.*\.pod#,
grep m#(?:\.pm|\.pod|_pm\.PL)#,
map {s/\s.*//s; $_}
grep { m#^(lib|ext|dist|cpan)/# && !m#/(?:t|demo|corpus)/# }
readline $manifest_fh;
close $manifest_fh
or die "$0: failed to close MANIFEST: $!";
my $out = open_new('pod/perlmodlib.pod', undef,
{by => "$0 extracting documentation",
from => 'the Perl source files'}, 1);
my %exceptions = (
'abbrev' => 'Text::Abbrev',
'carp' => 'Carp',
'getopt' => 'Getopt::Std',
'Encode::MIME::NAME' => 'Encode::MIME::Name',
'libnetFAQ' => 'Net::libnetFAQ',
);
my (@pragma, @mod);
for my $filename (@files) {
my $mod_fh;
unless (open $mod_fh, '<', $filename) {
warn "Couldn't open $filename: $!";
next;
}
my ($name, $thing);
my $foundit = 0;
{
local $/ = "";
while (readline $mod_fh) {
next unless /^=head1 NAME/;
$foundit++;
last;
}
}
unless ($foundit) {
next if pod_for_module_has_head1_NAME($filename);
die "p5p-controlled module $filename missing =head1 NAME\n"
if $filename !~ m{^(dist/|cpan/)}n # under our direct control
&& $filename !~ m{/_[^/]+\z} # not private
&& $filename ne 'lib/meta_notation.pm' # no pod
&& $filename ne 'lib/overload/numbers.pm'; # no pod
warn "$filename missing =head1 NAME\n" unless $Quiet;
next;
}
my $title = readline $mod_fh;
chomp $title;
close $mod_fh
or die "Error closing $filename: $!";
($name, $thing) = split /\s+--?\s+/, $title, 2;
unless ($name and $thing) {
warn "$filename missing name\n" unless $name;
warn "$filename missing thing\n" unless $thing or $Quiet;
next;
}
# unwrap C<...> around module name
if ($name =~ /^C<([A-Za-z0-9_:]+)>/) {
$name = $1;
}
$name =~ s/[^A-Za-z0-9_:\$<>].*//;
$name = $exceptions{$name} || $name;
$thing =~ s/^perl pragma to //i;
$thing = ucfirst $thing;
$title = "=item $name\n\n$thing\n\n";
if ($name =~ /[A-Z]/) {
push @mod, $title;
} else {
push @pragma, $title;
}
}
sub pod_for_module_has_head1_NAME {
my ($filename) = @_;
(my $pod_file = $filename) =~ s/\.pm\z/.pod/ or return 0;
return 0 if !-e $pod_file;
open my $fh, '<', $pod_file
or die "Can't open $pod_file for reading: $!\n";
local $/ = '';
while (my $para = <$fh>) {
return 1 if $para =~ /\A=head1 NAME$/m;
}
return 0;
}
# Much easier to special case it like this than special case the depending on
# and parsing lib/Config.pod, or special case opening configpm and finding its
# =head1 (which is not found with the $/="" above)
push @mod, "=item Config\n\nAccess Perl configuration information\n\n";
# The intent of using =cut as the heredoc terminator is to make the whole file
# parse as (reasonably) sane Pod as-is to anything that attempts to
# brute-force treat it as such. The content is already useful - this just
# makes it tidier, by stopping anything doing this mistaking the rest of the
# Perl code for Pod. eg https://metacpan.org/pod/perlmodlib
print $out <<'=cut';
=head1 NAME
perlmodlib - constructing new Perl modules and finding existing ones
=head1 THE PERL MODULE LIBRARY
Many modules are included in the Perl distribution. These are described
below, and all end in F<.pm>. You may discover compiled library
files (usually ending in F<.so>) or small pieces of modules to be
autoloaded (ending in F<.al>); these were automatically generated
by the installation process. You may also discover files in the
library directory that end in either F<.pl> or F<.ph>. These are
old libraries supplied so that old programs that use them still
run. The F<.pl> files will all eventually be converted into standard
modules, and the F<.ph> files made by B<h2ph> will probably end up
as extension modules made by B<h2xs>. (Some F<.ph> values may
already be available through the POSIX, Errno, or Fcntl modules.)
The B<pl2pm> file in the distribution may help in your conversion,
but it's just a mechanical process and therefore far from bulletproof.
=head2 Pragmatic Modules
They work somewhat like compiler directives (pragmata) in that they
tend to affect the compilation of your program, and thus will usually
work well only when used within a C<use>, or C<no>. Most of these
are lexically scoped, so an inner BLOCK may countermand them
by saying:
no integer;
no strict 'refs';
no warnings;
which lasts until the end of that BLOCK.
Some pragmas are lexically scoped--typically those that affect the
C<$^H> hints variable. Others affect the current package instead,
like C<use vars> and C<use subs>, which allow you to predeclare a
variables or subroutines within a particular I<file> rather than
just a block. Such declarations are effective for the entire file
for which they were declared. You cannot rescind them with C<no
vars> or C<no subs>.
The following pragmas are defined (and have their own documentation).
=over 12
=cut
print $out $_ for sort @pragma;
( run in 1.760 second using v1.01-cache-2.11-cpan-364913b4093 )