"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Doc/Doc.pm" between
PDL-2.082.tar.gz and PDL-2.083.tar.gz

About: PDL (Perl Data Language) aims to turn perl into an efficient numerical language for scientific computing (similar to IDL and MatLab).

Doc.pm  (PDL-2.082):Doc.pm  (PDL-2.083)
# the filter for the PDL pod format (which is a valid general perl # the filter for the PDL pod format (which is a valid general perl
# pod format but with special interpretation of some =for directives) # pod format but with special interpretation of some =for directives)
package PDL::PodParser; package PDL::PodParser;
use strict; use strict;
use warnings; use warnings;
use PDL::Core ''; use PDL::Core '';
use Pod::Select; use Pod::Select;
use File::Spec;
use File::Basename;
our @ISA = qw(Pod::Select); our @ISA = qw(Pod::Select);
our %Title = ('Example' => 'Example', our %Title = ('Example' => 'Example',
'Ref' => 'Reference', 'Ref' => 'Reference',
'Sig' => 'Signature', 'Sig' => 'Signature',
'Opt' => 'Options', 'Opt' => 'Options',
'Usage' => 'Usage', 'Usage' => 'Usage',
'Bad' => 'Bad value support', 'Bad' => 'Bad value support',
); );
skipping to change at line 108 skipping to change at line 106
sub checkmode { sub checkmode {
my ($this,$txt,$verbatim) = @_; my ($this,$txt,$verbatim) = @_;
if ($this->{Mode} =~ /NAME/ && $this->{Parmode} =~ /NAME/) { if ($this->{Mode} =~ /NAME/ && $this->{Parmode} =~ /NAME/) {
$this->{NAME} = $1 if $this->trim($txt) =~ /^\s*(\S+)\s*/; $this->{NAME} = $1 if $this->trim($txt) =~ /^\s*(\S+)\s*/;
print "\nNAME\t$this->{NAME}\n" if $this->{verbose}; print "\nNAME\t$this->{NAME}\n" if $this->{verbose};
$this->{Parmode} = 'Body'; $this->{Parmode} = 'Body';
return; return;
} }
unless ($this->{Parmode} =~ /Body/ || $this->{INBLOCK}) { unless ($this->{Parmode} =~ /Body/ || $this->{INBLOCK}) {
my $func = $this->{CURFUNC}; my $func = $this->{CURFUNC};
barf "no function defined" unless defined $func; die "no function defined\n" unless defined $func;
local $this->{INBLOCK} = 1; # can interpolate call textblock? local $this->{INBLOCK} = 1; # can interpolate call textblock?
my $itxt = $verbatim ? $txt : $this->interpolate($txt); my $itxt = $verbatim ? $txt : $this->interpolate($txt);
$this->{SYMHASH}->{$func}->{$this->{Parmode}} .= $this->{SYMHASH}->{$func}->{$this->{Parmode}} .=
$this->trim($itxt,$verbatim); $this->trim($itxt,$verbatim);
my $cr = ($verbatim && $this->{Parmode} ne 'Sig') ? "\n" : ""; my $cr = ($verbatim && $this->{Parmode} ne 'Sig') ? "\n" : "";
my $out = "\n\t\t$cr".$this->trim($itxt,$verbatim); my $out = "\n\t\t$cr".$this->trim($itxt,$verbatim);
print "$out\n$cr" if $this->{verbose}; print "$out\n$cr" if $this->{verbose};
} }
$this->{Parmode} = 'Body'; $this->{Parmode} = 'Body';
} }
skipping to change at line 158 skipping to change at line 156
return $ntxt; return $ntxt;
} }
=head1 NAME =head1 NAME
PDL::Doc - support for PDL online documentation PDL::Doc - support for PDL online documentation
=head1 SYNOPSIS =head1 SYNOPSIS
use PDL::Doc; use PDL::Doc;
$onlinedc = new PDL::Doc ($docfile); $onlinedc = PDL::Doc->new($docfile);
@match = $onlinedc->search('m/slice|clump/'); @match = $onlinedc->search('m/slice|clump/');
=head1 DESCRIPTION =head1 DESCRIPTION
An implementation of online docs for PDL. An implementation of online docs for PDL.
=head1 Using PDL documentation =head1 Using PDL documentation
PDL::Doc's main use is in the "help" (synonym "?") and "apropos" PDL::Doc's main use is in the "help" (synonym "?") and "apropos"
(synonym "??") commands in the perldl shell. PDL::Doc provides the (synonym "??") commands in the perldl shell. PDL::Doc provides the
skipping to change at line 386 skipping to change at line 384
a one line description of its intended functionality (suitable for a one line description of its intended functionality (suitable for
inclusion in a concise reference card). PP defined functions (see L<PDL::PP>) inclusion in a concise reference card). PP defined functions (see L<PDL::PP>)
should have a I<Sig> field stating their signature. To facilitate should have a I<Sig> field stating their signature. To facilitate
maintenance of this documentation for such functions the 'Doc' field maintenance of this documentation for such functions the 'Doc' field
has been introduced into the definition of C<pp_def> (see again L<PDL::PP>) has been introduced into the definition of C<pp_def> (see again L<PDL::PP>)
which will take care that name and signature of the so defined function which will take care that name and signature of the so defined function
are documented in this way (for examples of this usage see, for example, are documented in this way (for examples of this usage see, for example,
the PDL::Slices module, especially F<slices.pd> and the resulting the PDL::Slices module, especially F<slices.pd> and the resulting
F<Slices.pm>). Similarly, the 'BadDoc' field provides a means of F<Slices.pm>). Similarly, the 'BadDoc' field provides a means of
specifying information on how the routine handles the presence of specifying information on how the routine handles the presence of
bad values: this will be autpmatically created if bad values: this will be automatically created if
C<BadDoc> is not supplied, or set to C<undef>. C<BadDoc> is not supplied, or set to C<undef>.
Furthermore, the documentation for each function should contain Furthermore, the documentation for each function should contain
at least one of the I<Usage> or I<Examples> fields. Depending on the at least one of the I<Usage> or I<Examples> fields. Depending on the
calling conventions for the function under consideration presence calling conventions for the function under consideration presence
of both fields may be warranted. of both fields may be warranted.
If a function has options that should be given as a hash reference in If a function has options that should be given as a hash reference in
the form the form
skipping to change at line 415 skipping to change at line 413
alternatives. alternatives.
=cut =cut
package PDL::Doc; package PDL::Doc;
use strict; use strict;
use warnings; use warnings;
use PDL::Core ''; use PDL::Core '';
use File::Basename; use File::Basename;
use PDL::Doc::Config; use PDL::Doc::Config;
use File::Spec::Functions qw(file_name_is_absolute abs2rel rel2abs catdir catfil
e);
use Cwd (); # to help Debian packaging
=head1 INSTANCE METHODS =head1 INSTANCE METHODS
=head2 new =head2 new
$onlinedc = new PDL::Doc ('file.pdl',[more files]); $onlinedc = PDL::Doc->new('file.pdl',[more files]);
=cut =cut
sub new { sub new {
my ($type,@files) = @_; my ($type,@files) = @_;
my $this = bless {},$type; my $this = bless {},$type;
$this->{File} = [@files]; $this->{File} = [@files];
$this->{Scanned} = []; $this->{Scanned} = [];
$this->{Outfile} = $files[0]; $this->{Outfile} = $files[0];
return $this; return $this;
skipping to change at line 465 skipping to change at line 465
=head2 ensuredb =head2 ensuredb
Make sure that the database is slurped in Make sure that the database is slurped in
=cut =cut
sub ensuredb { sub ensuredb {
my ($this) = @_; my ($this) = @_;
while (my $fi = pop @{$this->{File}}) { while (my $fi = pop @{$this->{File}}) {
open IN, $fi or open my $fh, $fi or barf "can't open database $fi, scan docs first";
barf "can't open database $fi, scan docs first"; binmode $fh;
binmode IN;
my ($plen,$txt); my ($plen,$txt);
while (read IN, $plen,2) { while (read $fh, $plen,2) {
my ($len) = unpack "S", $plen; my ($len) = unpack "S", $plen;
read IN, $txt, $len; read $fh, $txt, $len;
my (@a) = split chr(0), $txt; my ($sym, $module, @a) = split chr(0), $txt;
my $module = splice @a,1,1; push @a, "" if @a % 2; # Add null string at end if necessary -- solves bug
push(@a, "") unless(@a % 2); # Add null string at end if necessary -- sol with missing REF section.
ves bug with missing REF section. $this->{SYMS}{$sym}{$module} = { @a, Dbfile => $fi }; # keep the origin pd
my ($sym, %hash) = @a; ldoc.db path
$hash{Dbfile} = $fi; # keep the origin pdldoc.db path
$this->{SYMS}->{$sym}->{$module} = {%hash};
} }
close IN;
push @{$this->{Scanned}}, $fi; push @{$this->{Scanned}}, $fi;
} }
return $this->{SYMS}; return $this->{SYMS};
} }
=head2 savedb =head2 savedb
save the database (i.e., the hash of PDL symbols) to the file associated save the database (i.e., the hash of PDL symbols) to the file associated
with this object. with this object.
=cut =cut
sub savedb { sub savedb {
my ($this) = @_; my ($this) = @_;
my $hash = $this->ensuredb(); my $hash = $this->ensuredb;
open my $fh, '>', $this->{Outfile} or barf "can't write to symdb $this->{Outfi le}: $!"; open my $fh, '>', $this->{Outfile} or barf "can't write to symdb $this->{Outfi le}: $!";
binmode $fh; binmode $fh;
while (my ($name,$mods_hash) = each %$hash) { while (my ($name,$mods_hash) = each %$hash) {
next if 0 == scalar(%$mods_hash); next if 0 == scalar(%$mods_hash);
while (my ($module,$val) = each %$mods_hash){ while (my ($module,$val) = each %$mods_hash) {
my $fi = $val->{File}; my $fi = $val->{File};
if (File::Spec->file_name_is_absolute($fi) && -f $fi) { $val->{File} = abs2rel($fi, dirname($this->{Outfile}))
#store paths to *.pm files relative to pdldoc.db #store paths to *.pm files relative to pdldoc.db
$val->{File} = File::Spec->abs2rel($fi, dirname($this->{Outfile})) ; if file_name_is_absolute($fi) && -f $fi;
}
delete $val->{Dbfile}; # no need to store Dbfile delete $val->{Dbfile}; # no need to store Dbfile
my $txt = join(chr(0),$name,$module,%$val); my $txt = join(chr(0),$name,$module,%$val);
print $fh pack("S",length($txt)).$txt; print $fh pack("S",length($txt)).$txt;
} }
} }
} }
=head2 gethash =head2 gethash
Return the PDL symhash (e.g. for custom search operations) Return the PDL symhash (e.g. for custom search operations). To see what
it has stored in it in JSON format:
perl -MPDL::Doc -MJSON::PP -e \
'print encode_json +PDL::Doc->new(PDL::Doc::_find_inc([qw(PDL pdldoc.db)]))-
>gethash' |
json_pp -json_opt pretty,canonical
The symhash is a multiply nested hash ref with the following structure: The symhash is a multiply nested hash ref with the following structure:
$symhash = { $symhash = {
function_name => { function_name => {
module::name => { module::name => {
Module => 'module::name', Module => 'module::name',
Sig => 'signature string', Sig => 'signature string',
Bad => 'bad documentation string', Bad => 'bad documentation string',
... ...
skipping to change at line 557 skipping to change at line 555
names (ex: the documentation for zeros is under zeroes) names (ex: the documentation for zeros is under zeroes)
Names - a comma-separated string of all the function's names Names - a comma-separated string of all the function's names
Example - example text (optional) Example - example text (optional)
Ref - one-line reference string Ref - one-line reference string
Opt - options Opt - options
Usage - short usage explanation Usage - short usage explanation
Bad - explanation of behavior when it encounters bad values Bad - explanation of behavior when it encounters bad values
=cut =cut
sub gethash { sub gethash { $_[0]->ensuredb }
return $_[0]->ensuredb();
}
=head2 search =head2 search
Search a PDL symhash Search a PDL symhash
=for usage =for usage
$onldc->search($regex, $fields [, $sort]) $onldc->search($regex, $fields [, $sort])
Searching is by default case insensitive. Other flags can be Searching is by default case insensitive. Other flags can be
skipping to change at line 611 skipping to change at line 607
$sort = 0 unless defined $sort; $sort = 0 unless defined $sort;
my $hash = $this->ensuredb; my $hash = $this->ensuredb;
my @match = (); my @match = ();
# Make a single scalar $fields work # Make a single scalar $fields work
$fields = [$fields] if ref($fields) eq ''; $fields = [$fields] if ref($fields) eq '';
$pattern = $this->checkregex($pattern); $pattern = $this->checkregex($pattern);
while (my ($name,$mods_hash) = each %$hash) { while (my ($name,$mods_hash) = each %$hash) {
while (my ($module,$val) = each %$mods_hash){ while (my ($module,$val) = each %$mods_hash) {
FIELD: for (@$fields) { FIELD: for (@$fields) {
if ($_ eq 'Name' and $name =~ /$pattern/i if ($_ eq 'Name' and $name =~ /$pattern/i
or defined $val->{$_} and $val->{$_} =~ /$pattern/i) { or defined $val->{$_} and $val->{$_} =~ /$pattern/i) {
$val = $hash->{$val->{Crossref}}->{$module} #we're going to assum e that any Crossref'd documentation is also in this module $val = $hash->{$val->{Crossref}}->{$module} #we're going to assum e that any Crossref'd documentation is also in this module
if defined $val->{Crossref} && defined $hash->{$val->{Crossref}}- >{$module}; if defined $val->{Crossref} && defined $hash->{$val->{Crossref}}- >{$module};
push @match, [$name,$module,$val]; push @match, [$name,$module,$val];
last FIELD; last FIELD;
} }
} }
} }
skipping to change at line 655 skipping to change at line 651
=head2 scan =head2 scan
Scan a source file using the PDL podparser to extract information Scan a source file using the PDL podparser to extract information
for online documentation for online documentation
=cut =cut
sub scan { sub scan {
my ($this,$file,$verbose) = @_; my ($this,$file,$verbose) = @_;
$verbose = 0 unless defined $verbose;
barf "can't find file '$file'" unless -f $file; barf "can't find file '$file'" unless -f $file;
$file = Cwd::abs_path($file); # help Debian packaging
# First HTMLify file in the tree $verbose = 0 unless defined $verbose;
# Does not work yet
#if (system ("pod2html $file")!=0) {
# warn "Failed to execute command: pod2html $file2\n";
#}
#else{ # Rename result (crummy pod2html)
# rename ("$file.html","$1.html") if $file =~ /^(.*)\.pm$/;
#}
# Now parse orig pm/pod
open my $infile, '<', $file; open my $infile, '<', $file;
# XXXX convert to absolute path # XXXX convert to absolute path
# my $outfile = '/tmp/'.basename($file).'.pod'; # my $outfile = '/tmp/'.basename($file).'.pod';
open my $outfile, '>', \(my $outfile_text); open my $outfile, '>', \(my $outfile_text);
# Handle RPM etc. case where we are building away from the final # Handle RPM etc. case where we are building away from the final
# location. Alright it's a hack - KGB # location. Alright it's a hack - KGB
my $file2 = $file; my $file2 = $file;
$file2 =~ s/^$ENV{BUILDROOTPREFIX}// if $ENV{BUILDROOTPREFIX}; $file2 =~ s/^$ENV{BUILDROOTPREFIX}// if $ENV{BUILDROOTPREFIX};
my $parser = PDL::PodParser->new; my $parser = PDL::PodParser->new;
$parser->{verbose} = $verbose; $parser->{verbose} = $verbose;
eval { $parser->parse_from_filehandle($infile,$outfile) }; eval { $parser->parse_from_filehandle($infile,$outfile) };
warn "cannot parse '$file' ($@)" if $@; warn "cannot parse '$file' ($@)" if $@ and $@ ne "no function defined\n";
$this->{SYMS} = {} unless defined $this->{SYMS}; my $hash = $this->{SYMS} ||= {};
my $hash = $this->{SYMS};
my @stats = stat $file;
$this->{FTIME}->{$file2} = $stats[9]; # store last mod time
# print "mtime of $file: $stats[9]\n";
my $n = 0; my $n = 0;
$_->{File} = $file2, $n++ for values %{ $parser->{SYMHASH} };
while (my ($key,$val) = each %{ $parser->{SYMHASH} }) { while (my ($key,$val) = each %{ $parser->{SYMHASH} }) {
$n++;
$val->{File} = $file2;
#set up the 3-layer hash/database structure: $hash->{funcname}->{PDL::SomeMo dule} = $val #set up the 3-layer hash/database structure: $hash->{funcname}->{PDL::SomeMo dule} = $val
if (defined($val->{Module})){ if (defined($val->{Module})) {
$hash->{$key}->{$val->{Module}} = $val; $hash->{$key}{$val->{Module}} = $val;
} else { } else {
warn "no Module for $key in $file2\n"; warn "no Module for $key in $file2\n";
} }
} }
# KGB pass2 - scan for module name and function # KGB pass2 - scan for module name and function
# alright I admit this is kludgy but it works # alright I admit this is kludgy but it works
# and one can now find modules with 'apropos' # and one can now find modules with 'apropos'
open $infile, '<', $file; open $infile, '<', $file;
$outfile_text = ''; $outfile_text = '';
$parser = new PDL::PodParser; $parser = PDL::PodParser->new;
$parser->select('NAME'); $parser->select('NAME');
eval { $parser->parse_from_filehandle($infile,$outfile) }; eval { $parser->parse_from_filehandle($infile,$outfile) };
warn "cannot parse '$file'" if $@; warn "cannot parse '$file'" if $@;
my @namelines = split("\n",$outfile_text); my @namelines = split("\n",$outfile_text);
my ($name,$does); my ($name,$does);
for (@namelines) { for (@namelines) {
if (/^(PDL) (-) (.*)/ or /^\s*(Inline::Pdlpp)\s*(-*)?\s*(.*)\s*$/ or /\s*( PDL::[\w:]*)\s*(-*)?\s*(.*)\s*$/) { if (/^(PDL) (-) (.*)/ or /^\s*(Inline::Pdlpp)\s*(-*)?\s*(.*)\s*$/ or /\s*( PDL::[\w:]*)\s*(-*)?\s*(.*)\s*$/) {
$name = $1; $does = $3; $name = $1; $does = $3;
} }
skipping to change at line 748 skipping to change at line 727
documentation) files (using the File::Find module). documentation) files (using the File::Find module).
=cut =cut
sub scantree { sub scantree {
my ($this,$dir,$verbose) = @_; my ($this,$dir,$verbose) = @_;
$verbose = 0 unless defined $verbose; $verbose = 0 unless defined $verbose;
require File::Find; require File::Find;
print "Scanning $dir ... \n\n"; print "Scanning $dir ... \n\n";
my $ntot = 0; my $ntot = 0;
my $sub = sub { if (($File::Find::name =~ /[.]pm$/ && my $sub = sub {
$File::Find::name !~ /PP.pm/ && return if $File::Find::name !~ /\.(?:pm|pod)$/;
$File::Find::name !~ m|Pod/Parser.pm| && return if $File::Find::name =~ /(?:Index\.pod|PP\.pm)$/ or
$File::Find::dir !~ m#/PP|/Gen#) or ( $File::Find::dir =~ m#/PP#;
$File::Find::name =~ /[.]pod$/ && printf "%-20s", $_.'...';
$File::Find::name !~ /Index[.]pod$/)){ $ntot += my $n = $this->scan($File::Find::name,$verbose);
printf "%-20s", $_.'...'; print "\t$n functions\n";
my $n = $this->scan($File::Find::name,$verbose); # bind $this lexically
print "\t$n functions\n";
$ntot += $n;
}
}; };
File::Find::find($sub,$dir); File::Find::find($sub,$dir);
print "\n\nfound $ntot functions\n"; print "\nfound $ntot functions\n";
$ntot;
} }
=head2 funcdocs =head2 funcdocs
extract the complete documentation about a function from its extract the complete documentation about a function from its
source file using the PDL::PodParser filter. source file using the PDL::PodParser filter.
=cut =cut
sub funcdocs { sub funcdocs {
my ($this,$func,$module,$fout) = @_; my ($this,$func,$module,$fout) = @_;
my $hash = $this->ensuredb; my $hash = $this->ensuredb;
barf "unknown function '$func'" unless defined($hash->{$func}); barf "unknown function '$func'" unless defined($hash->{$func});
barf "funcdocs now requires 3 arguments" if defined fileno $module; barf "funcdocs now requires 3 arguments" if defined fileno $module;
my $file = $hash->{$func}->{$module}->{File}; my $file = $hash->{$func}{$module}{File};
my $dbf = $hash->{$func}->{$module}->{Dbfile}; my $dbf = $hash->{$func}{$module}{Dbfile};
if (!File::Spec->file_name_is_absolute($file) && $dbf) { $file = Cwd::abs_path($file) if file_name_is_absolute($file);
$file = File::Spec->rel2abs($file, dirname($dbf)); $dbf = Cwd::abs_path($dbf); # help Debian packaging
} $file = rel2abs($file, dirname($dbf))
if !file_name_is_absolute($file) && $dbf;
funcdocs_fromfile($func,$file,$fout); funcdocs_fromfile($func,$file,$fout);
} }
=head1 FUNCTIONS =head1 FUNCTIONS
=cut =cut
sub funcdocs_fromfile { sub funcdocs_fromfile {
my ($func,$file) = @_; my ($func,$file) = @_;
barf "can't find file '$file'" unless -f $file; barf "can't find file '$file'" unless -f $file;
skipping to change at line 822 skipping to change at line 799
seek $in,0,0; seek $in,0,0;
$parser->select("$foo/(.*,\\s+)*$func(\\(.*\\))*(\\s*|,\\s+.*)"); $parser->select("$foo/(.*,\\s+)*$func(\\(.*\\))*(\\s*|,\\s+.*)");
$parser->parse_from_filehandle($in,$out); $parser->parse_from_filehandle($in,$out);
} }
} }
=head2 add_module =head2 add_module
=for usage =for usage
use PDL::Doc; PDL::Doc::add_module("my::module"); use PDL::Doc;
PDL::Doc::add_module("PDL::Stats"); # add PDL::Stats, PDL::Stats::GLM, ...
=for ref =for ref
The C<add_module> function allows you to add POD from a particular Perl The C<add_module> function allows you to add POD from a particular Perl
module that you've installed somewhere in @INC. It searches for the module (and as of PDL 2.083, in fact all modules starting with that as
a prefix) that you've installed somewhere in C<@INC>. It searches for the
active PDL document database and the module's .pod and .pm files, and active PDL document database and the module's .pod and .pm files, and
scans and indexes the module into the database. scans and indexes the module(s) into the database.
C<add_module> is meant to be added to your module's Makefile as part of the C<add_module> is meant to be added to your module's Makefile as part of the
installation script. installation script. This is done automatically by
L<PDL::Core::Dev/pdlpp_postamble>, but if the top level of your
=cut distribution is Perl modules (like L<PDL::LinearAlgebra>), then add a
C<postamble> manually in the F<Makefile.PL>:
sub add_module { use PDL::Core::Dev;
my($module) = shift; sub MY::postamble {
use File::Copy qw{copy}; my $oneliner = PDL::Core::Dev::_oneliner(qq{exit if \$ENV{DESTDIR}; use PDL:
my($pdldoc); :Doc; eval { PDL::Doc::add_module(shift); }});
local($_); qq|\ninstall :: pure_install\n\t$oneliner \$(NAME)\n|;
DIRECTORY: }
for my $dir (@INC){
my $file = $dir."/PDL/pdldoc.db";
if( -f $file) {
if(! -w "$dir/PDL") {
die "No write permission at $dir/PDL - not updating docs database
.\n";
}
print "Found docs database $file\n";
$pdldoc = PDL::Doc->new($file);
last DIRECTORY;
}
}
die "Unable to find docs database - therefore not updating it.\n" unless($pd ldoc); =cut
my $mfile = $module; sub _find_inc {
$mfile =~ s/\:\:/\//g; my ($what, $want_dir) = @_;
for(@INC){ my @ret;
my $postfix; for my $dir (@INC) {
my $hit = 0; my $ent = $want_dir ? catdir($dir, @$what) : catfile($dir, @$what);
for $postfix(".pm",".pod") { push @ret, $ent if $want_dir ? -d $ent : -f $ent;
my $f = "$_/$mfile$postfix"; }
if( -e $f ){ @ret;
$pdldoc->ensuredb(); }
$pdldoc->scan($f);
eval { $pdldoc->savedb(); };
warn $@ if $@;
print "PDL docs database updated - added $f.\n";
$hit = 1;
}
}
return if($hit);
}
die "Unable to find a .pm or .pod file in \@INC for module $module\n"; sub add_module {
my ($module) = @_;
my ($file) = _find_inc([qw(PDL pdldoc.db)], 0);
die "Unable to find docs database - therefore not updating it.\n" if !defined
$file;
die "No write permission for $file - not updating docs database.\n"
if !-w $file;
print "Found docs database $file\n";
my $pdldoc = PDL::Doc->new($file);
my @pkg = my @mfile = split /::/, $module;
my $mlast = pop @mfile;
my @found = map _find_inc([@mfile, $mlast.$_]), qw(.pm .pod);
die "Unable to find a .pm or .pod file in \@INC for module $module\n" if !@fou
nd;
$pdldoc->ensuredb;
my $n = 0;
$n += $pdldoc->scan($_) for @found;
print "Added @found, $n functions.\n";
$n += $pdldoc->scantree($_) for _find_inc(\@pkg, 1);
eval { $pdldoc->savedb; };
warn $@ if $@;
print "PDL docs database updated - total $n functions.\n";
} }
=head1 PDL::DOC EXAMPLE =head1 PDL::DOC EXAMPLE
Here's an example of how you might use the PDL Doc database in your Here's an example of how you might use the PDL Doc database in your
own code. own code.
use PDL::Doc; use PDL::Doc;
# Find the pdl documentation # Find the pdl documentation
my ($dir,$file,$pdldoc); my ($file) = _find_inc([qw(PDL pdldoc.db)], 0);
DIRECTORY: for $dir (@INC) { die "Unable to find docs database!\n" unless defined $file;
$file = $dir."/PDL/pdldoc.db"; print "Found docs database $file\n";
if (-f $file) { my $pdldoc = PDL::Doc->new($file);
print "Found docs database $file\n";
$pdldoc = new PDL::Doc ($file);
last DIRECTORY;
}
}
die ("Unable to find docs database!\n") unless $pdldoc;
# Print the reference line for zeroes: # Print the reference line for zeroes:
print map{$_->{Ref}} values %{$pdldoc->gethash->{zeroes}}; print map{$_->{Ref}} values %{$pdldoc->gethash->{zeroes}};
# Or, if you remember that zeroes is in PDL::Core: # Or, if you remember that zeroes is in PDL::Core:
print $pdldoc->gethash->{zeroes}->{PDL::Core}->{Ref}; print $pdldoc->gethash->{zeroes}->{PDL::Core}->{Ref};
# Get info for all the functions whose examples use zeroes # Get info for all the functions whose examples use zeroes
my @entries = $pdldoc->search('zeroes','Example',1); my @entries = $pdldoc->search('zeroes','Example',1);
# All the functions that use zeroes in their example: # All the functions that use zeroes in their example:
print "Functions that use 'zeroes' in their examples include:\n"; print "Functions that use 'zeroes' in their examples include:\n";
foreach my $entry (@entries) { foreach my $entry (@entries) {
# Unpack the entry # Unpack the entry
my ($func_name, $module, $sym_hash) = @$entry; my ($func_name, $module, $sym_hash) = @$entry;
print "$func_name\n"; print "$func_name\n";
} }
print "\n"; print "\n";
#Or, more concisely: #Or, more concisely:
print join("\n",map{$_->[0]}@entries); print map "$_->[0]\n", @entries;
# Let's look at the function 'mpdl' # Let's look at the function 'mpdl'
@entries = $pdldoc->search('mpdl', 'Name'); @entries = $pdldoc->search('mpdl', 'Name');
# I know there's only one: # I know there's only one:
my $entry = $entries[0]; my $entry = $entries[0];
my ($func_name, undef, $sym_hash) = @$entry; my ($func_name, undef, $sym_hash) = @$entry;
print "mpdl info:\n"; print "mpdl info:\n";
foreach my $key (sort keys %$sym_hash) { foreach my $key (sort keys %$sym_hash) {
# Unpack the entry # Unpack the entry
print "---$key---\n$sym_hash->{$key}\n"; print "---$key---\n$sym_hash->{$key}\n";
 End of changes. 38 change blocks. 
129 lines changed or deleted 104 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)